Merge pull request #1371 from LukasKorba/1368-Handle-any-lightwalletd-error-with-retry-logic

[#1368] Handle any lightwalletd error with retry logic
This commit is contained in:
Lukas Korba 2024-02-12 17:40:41 +01:00 committed by GitHub
commit 25e844115d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 14 deletions

View File

@ -40,7 +40,7 @@ actor CompactBlockProcessor {
private let fileManager: ZcashFileManager private let fileManager: ZcashFileManager
private var retryAttempts: Int = 0 private var retryAttempts: Int = 0
private var blockStreamRetryAttempts: Int = 0 private var serviceFailureRetryAttempts: Int = 0
private var backoffTimer: Timer? private var backoffTimer: Timer?
private var consecutiveChainValidationErrors: Int = 0 private var consecutiveChainValidationErrors: Int = 0
@ -264,7 +264,7 @@ extension CompactBlockProcessor {
func start(retry: Bool = false) async { func start(retry: Bool = false) async {
if retry { if retry {
self.retryAttempts = 0 self.retryAttempts = 0
self.blockStreamRetryAttempts = 0 self.serviceFailureRetryAttempts = 0
self.backoffTimer?.invalidate() self.backoffTimer?.invalidate()
self.backoffTimer = nil self.backoffTimer = nil
} }
@ -291,7 +291,7 @@ extension CompactBlockProcessor {
self.backoffTimer = nil self.backoffTimer = nil
await stopAllActions() await stopAllActions()
retryAttempts = 0 retryAttempts = 0
blockStreamRetryAttempts = 0 serviceFailureRetryAttempts = 0
} }
func latestHeight() async throws -> BlockHeight { func latestHeight() async throws -> BlockHeight {
@ -579,13 +579,23 @@ extension CompactBlockProcessor {
await stopAllActions() await stopAllActions()
logger.error("Sync failed with error: \(error)") logger.error("Sync failed with error: \(error)")
// catching the block stream error // catching the service errors
if case ZcashError.serviceBlockStreamFailed = error, self.blockStreamRetryAttempts < ZcashSDK.blockStreamRetries { let serviceError: Bool
// This may be false positive communication error that is usually resolved by retry. switch error {
// We will try to reset the sync and continue but this will we done at most `ZcashSDK.blockStreamRetries` times. case ZcashError.serviceGetInfoFailed, ZcashError.serviceLatestBlockFailed,
logger.error("ZcashError.serviceBlockStreamFailed, retry is available, starting the sync all over again.") ZcashError.serviceLatestBlockHeightFailed, ZcashError.serviceBlockRangeFailed,
ZcashError.serviceSubmitFailed, ZcashError.serviceFetchTransactionFailed,
ZcashError.serviceFetchUTXOsFailed, ZcashError.serviceBlockStreamFailed,
ZcashError.serviceSubtreeRootsStreamFailed: serviceError = true
default: serviceError = false
}
self.blockStreamRetryAttempts += 1 if serviceError && self.serviceFailureRetryAttempts < ZcashSDK.serviceFailureRetries {
// This may be false positive communication error that is usually resolved by retry.
// We will try to reset the sync and continue but this will we done at most `ZcashSDK.serviceFailureRetries` times.
logger.error("ServiceError: \(error), retry is available, starting the sync all over again.")
self.serviceFailureRetryAttempts += 1
// Start sync all over again // Start sync all over again
await resetContext() await resetContext()
@ -694,7 +704,7 @@ extension CompactBlockProcessor {
latestBlockHeightWhenSyncing > 0 && latestBlockHeightWhenSyncing < latestBlockHeight latestBlockHeightWhenSyncing > 0 && latestBlockHeightWhenSyncing < latestBlockHeight
retryAttempts = 0 retryAttempts = 0
blockStreamRetryAttempts = 0 serviceFailureRetryAttempts = 0
consecutiveChainValidationErrors = 0 consecutiveChainValidationErrors = 0
let lastScannedHeight = await latestBlocksDataProvider.maxScannedHeight let lastScannedHeight = await latestBlocksDataProvider.maxScannedHeight

View File

@ -105,10 +105,9 @@ public enum ZcashSDK {
// TODO: [#1304] smart retry logic, https://github.com/zcash/ZcashLightClientKit/issues/1304 // TODO: [#1304] smart retry logic, https://github.com/zcash/ZcashLightClientKit/issues/1304
public static let defaultRetries = Int.max public static let defaultRetries = Int.max
/// The communication errors are represented as serviceBlockStreamFailed : LightWalletServiceError, unavailable 14 /// The communication errors are usually false positive and another try will continue the work,
/// These cases are usually false positive and another try will continue the work, in case the service is trully down we /// in case the service is trully down we cap the amount of retries by this value.
/// cap the amount of retries by this value. public static let serviceFailureRetries = 3
public static let blockStreamRetries = 3
/// The default maximum amount of time to wait during retry backoff intervals. Failed loops will never wait longer than /// The default maximum amount of time to wait during retry backoff intervals. Failed loops will never wait longer than
/// this before retrying. /// this before retrying.