diff options
author | Florian Dold <florian@dold.me> | 2022-09-05 18:12:30 +0200 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2022-09-13 16:10:41 +0200 |
commit | 13e7a674778754c0ed641dfd428e3d6b2b71ab2d (patch) | |
tree | f2a0e5029305a9b818416fd94908ef77cdd7446f /packages/taler-wallet-core/src/operations/recoup.ts | |
parent | f9f2911c761af1c8ed1c323dcd414cbaa9eeae7c (diff) | |
download | wallet-core-13e7a674778754c0ed641dfd428e3d6b2b71ab2d.tar.xz |
wallet-core: uniform retry handling
Diffstat (limited to 'packages/taler-wallet-core/src/operations/recoup.ts')
-rw-r--r-- | packages/taler-wallet-core/src/operations/recoup.ts | 85 |
1 files changed, 14 insertions, 71 deletions
diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts index 283707947..387c23f41 100644 --- a/packages/taler-wallet-core/src/operations/recoup.ts +++ b/packages/taler-wallet-core/src/operations/recoup.ts @@ -42,6 +42,8 @@ import { CoinRecord, CoinSourceType, CoinStatus, + OperationAttemptResult, + OperationAttemptResultType, RecoupGroupRecord, RefreshCoinSource, ReserveRecordStatus, @@ -52,64 +54,13 @@ import { import { InternalWalletState } from "../internal-wallet-state.js"; import { readSuccessResponseJsonOrThrow } from "../util/http.js"; import { GetReadWriteAccess } from "../util/query.js"; -import { RetryInfo } from "../util/retries.js"; +import { RetryInfo, runOperationHandlerForResult } from "../util/retries.js"; import { guardOperationException } from "./common.js"; import { createRefreshGroup, processRefreshGroup } from "./refresh.js"; import { internalCreateWithdrawalGroup } from "./withdraw.js"; const logger = new Logger("operations/recoup.ts"); -async function setupRecoupRetry( - ws: InternalWalletState, - recoupGroupId: string, - options: { - reset: boolean; - }, -): Promise<void> { - await ws.db - .mktx((x) => ({ - recoupGroups: x.recoupGroups, - })) - .runReadWrite(async (tx) => { - const r = await tx.recoupGroups.get(recoupGroupId); - if (!r) { - return; - } - if (options.reset) { - r.retryInfo = RetryInfo.reset(); - } else { - r.retryInfo = RetryInfo.increment(r.retryInfo); - } - delete r.lastError; - await tx.recoupGroups.put(r); - }); -} - -async function reportRecoupError( - ws: InternalWalletState, - recoupGroupId: string, - err: TalerErrorDetail, -): Promise<void> { - await ws.db - .mktx((x) => ({ - recoupGroups: x.recoupGroups, - })) - .runReadWrite(async (tx) => { - const r = await tx.recoupGroups.get(recoupGroupId); - if (!r) { - return; - } - if (!r.retryInfo) { - logger.error( - "reporting error for inactive recoup group (no retry info)", - ); - } - r.lastError = err; - await tx.recoupGroups.put(r); - }); - ws.notify({ type: NotificationType.RecoupOperationError, error: err }); -} - /** * Store a recoup group record in the database after marking * a coin in the group as finished. @@ -353,25 +304,20 @@ export async function processRecoupGroup( forceNow?: boolean; } = {}, ): Promise<void> { - await ws.memoProcessRecoup.memo(recoupGroupId, async () => { - const onOpErr = (e: TalerErrorDetail): Promise<void> => - reportRecoupError(ws, recoupGroupId, e); - return await guardOperationException( - async () => await processRecoupGroupImpl(ws, recoupGroupId, options), - onOpErr, - ); - }); + await runOperationHandlerForResult( + await processRecoupGroupHandler(ws, recoupGroupId, options), + ); + return; } -async function processRecoupGroupImpl( +export async function processRecoupGroupHandler( ws: InternalWalletState, recoupGroupId: string, options: { forceNow?: boolean; } = {}, -): Promise<void> { +): Promise<OperationAttemptResult> { const forceNow = options.forceNow ?? false; - await setupRecoupRetry(ws, recoupGroupId, { reset: forceNow }); let recoupGroup = await ws.db .mktx((x) => ({ recoupGroups: x.recoupGroups, @@ -380,11 +326,11 @@ async function processRecoupGroupImpl( return tx.recoupGroups.get(recoupGroupId); }); if (!recoupGroup) { - return; + return OperationAttemptResult.finishedEmpty(); } if (recoupGroup.timestampFinished) { logger.trace("recoup group finished"); - return; + return OperationAttemptResult.finishedEmpty(); } const ps = recoupGroup.coinPubs.map(async (x, i) => { try { @@ -404,12 +350,12 @@ async function processRecoupGroupImpl( return tx.recoupGroups.get(recoupGroupId); }); if (!recoupGroup) { - return; + return OperationAttemptResult.finishedEmpty(); } for (const b of recoupGroup.recoupFinishedPerCoin) { if (!b) { - return; + return OperationAttemptResult.finishedEmpty(); } } @@ -480,8 +426,6 @@ async function processRecoupGroupImpl( return; } rg2.timestampFinished = TalerProtocolTimestamp.now(); - rg2.retryInfo = RetryInfo.reset(); - rg2.lastError = undefined; if (rg2.scheduleRefreshCoins.length > 0) { const refreshGroupId = await createRefreshGroup( ws, @@ -495,6 +439,7 @@ async function processRecoupGroupImpl( } await tx.recoupGroups.put(rg2); }); + return OperationAttemptResult.finishedEmpty(); } export async function createRecoupGroup( @@ -514,10 +459,8 @@ export async function createRecoupGroup( recoupGroupId, exchangeBaseUrl: exchangeBaseUrl, coinPubs: coinPubs, - lastError: undefined, timestampFinished: undefined, timestampStarted: TalerProtocolTimestamp.now(), - retryInfo: RetryInfo.reset(), recoupFinishedPerCoin: coinPubs.map(() => false), // Will be populated later oldAmountPerCoin: [], |