[#1368] Handle any lightwalletd error with retry logic
- The retry logic was implemented for blockStream errors only but this PR generalize it for any lightwalletd error
This commit is contained in:
parent
09fe70dff2
commit
99d4821769
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue