From c265e7d019d445add2d2cfb7cfcbdeee059684d3 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Tue, 29 Mar 2022 13:47:32 +0200 Subject: wallet: make retries more robust and consistent --- .../taler-wallet-core/src/operations/withdraw.ts | 81 ++++++++++++---------- 1 file changed, 46 insertions(+), 35 deletions(-) (limited to 'packages/taler-wallet-core/src/operations/withdraw.ts') diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 4a7adbb9c..e7dcd0784 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -68,7 +68,11 @@ import { HttpRequestLibrary, readSuccessResponseJsonOrThrow, } from "../util/http.js"; -import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries.js"; +import { + resetRetryInfo, + RetryInfo, + updateRetryInfoTimeout, +} from "../util/retries.js"; import { WALLET_BANK_INTEGRATION_PROTOCOL_VERSION, WALLET_EXCHANGE_PROTOCOL_VERSION, @@ -792,10 +796,33 @@ export async function updateWithdrawalDenoms( } } -async function incrementWithdrawalRetry( +async function setupWithdrawalRetry( + ws: InternalWalletState, + withdrawalGroupId: string, + options: { + reset: boolean; + }, +): Promise { + await ws.db + .mktx((x) => ({ withdrawalGroups: x.withdrawalGroups })) + .runReadWrite(async (tx) => { + const wsr = await tx.withdrawalGroups.get(withdrawalGroupId); + if (!wsr) { + return; + } + if (options.reset) { + wsr.retryInfo = resetRetryInfo(); + } else { + wsr.retryInfo = RetryInfo.increment(wsr.retryInfo); + } + await tx.withdrawalGroups.put(wsr); + }); +} + +async function reportWithdrawalError( ws: InternalWalletState, withdrawalGroupId: string, - err: TalerErrorDetail | undefined, + err: TalerErrorDetail, ): Promise { await ws.db .mktx((x) => ({ withdrawalGroups: x.withdrawalGroups })) @@ -804,56 +831,40 @@ async function incrementWithdrawalRetry( if (!wsr) { return; } - wsr.retryInfo.retryCounter++; - updateRetryInfoTimeout(wsr.retryInfo); + if (!wsr.retryInfo) { + logger.reportBreak(); + } wsr.lastError = err; await tx.withdrawalGroups.put(wsr); }); - if (err) { - ws.notify({ type: NotificationType.WithdrawOperationError, error: err }); - } + ws.notify({ type: NotificationType.WithdrawOperationError, error: err }); } export async function processWithdrawGroup( ws: InternalWalletState, withdrawalGroupId: string, - forceNow = false, + options: { + forceNow?: boolean; + } = {}, ): Promise { const onOpErr = (e: TalerErrorDetail): Promise => - incrementWithdrawalRetry(ws, withdrawalGroupId, e); + reportWithdrawalError(ws, withdrawalGroupId, e); await guardOperationException( - () => processWithdrawGroupImpl(ws, withdrawalGroupId, forceNow), + () => processWithdrawGroupImpl(ws, withdrawalGroupId, options), onOpErr, ); } -async function resetWithdrawalGroupRetry( - ws: InternalWalletState, - withdrawalGroupId: string, -): Promise { - await ws.db - .mktx((x) => ({ - withdrawalGroups: x.withdrawalGroups, - reserves: x.reserves, - })) - .runReadWrite(async (tx) => { - const x = await tx.withdrawalGroups.get(withdrawalGroupId); - if (x) { - x.retryInfo = initRetryInfo(); - await tx.withdrawalGroups.put(x); - } - }); -} - async function processWithdrawGroupImpl( ws: InternalWalletState, withdrawalGroupId: string, - forceNow: boolean, + options: { + forceNow?: boolean; + } = {}, ): Promise { + const forceNow = options.forceNow ?? false; logger.trace("processing withdraw group", withdrawalGroupId); - if (forceNow) { - await resetWithdrawalGroupRetry(ws, withdrawalGroupId); - } + await setupWithdrawalRetry(ws, withdrawalGroupId, { reset: forceNow }); const withdrawalGroup = await ws.db .mktx((x) => ({ withdrawalGroups: x.withdrawalGroups })) .runReadOnly(async (tx) => { @@ -876,7 +887,7 @@ async function processWithdrawGroupImpl( ); return; } - return await ws.reserveOps.processReserve(ws, reservePub, forceNow); + return await ws.reserveOps.processReserve(ws, reservePub, { forceNow }); } await ws.exchangeOps.updateExchangeFromUrl( @@ -948,7 +959,7 @@ async function processWithdrawGroupImpl( wg.timestampFinish = TalerProtocolTimestamp.now(); wg.operationStatus = OperationStatus.Finished; delete wg.lastError; - wg.retryInfo = initRetryInfo(); + wg.retryInfo = resetRetryInfo(); } await tx.withdrawalGroups.put(wg); -- cgit v1.2.3