diff options
Diffstat (limited to 'packages/taler-wallet-core/src')
-rw-r--r-- | packages/taler-wallet-core/src/refresh.ts | 96 |
1 files changed, 34 insertions, 62 deletions
diff --git a/packages/taler-wallet-core/src/refresh.ts b/packages/taler-wallet-core/src/refresh.ts index a8f1cc61d..05c65f6b6 100644 --- a/packages/taler-wallet-core/src/refresh.ts +++ b/packages/taler-wallet-core/src/refresh.ts @@ -29,7 +29,6 @@ import { Amounts, amountToPretty, assertUnreachable, - AsyncFlag, checkDbInvariant, codecForCoinHistoryResponse, codecForExchangeMeltResponse, @@ -75,6 +74,7 @@ import { } from "@gnu-taler/taler-util/http"; import { constructTaskIdentifier, + genericWaitForState, makeCoinsVisible, PendingTaskType, TaskIdStr, @@ -1847,66 +1847,38 @@ export async function waitRefreshFinal( const ctx = new RefreshTransactionContext(wex, refreshGroupId); wex.taskScheduler.startShepherdTask(ctx.taskId); - // FIXME: Clean up using the new JS "using" / Symbol.dispose syntax. - const refreshNotifFlag = new AsyncFlag(); - // Raise purchaseNotifFlag whenever we get a notification - // about our refresh. - const cancelNotif = wex.ws.addNotificationListener((notif) => { - if ( - notif.type === NotificationType.TransactionStateTransition && - notif.transactionId === ctx.transactionId - ) { - refreshNotifFlag.raise(); - } - }); - const unregisterOnCancelled = wex.cancellationToken.onCancelled(() => { - cancelNotif(); - refreshNotifFlag.raise(); + await genericWaitForState(wex, { + async checkState(): Promise<boolean> { + // Check if refresh is final + const res = await ctx.wex.db.runReadOnlyTx( + { storeNames: ["refreshGroups"] }, + async (tx) => { + return { + rg: await tx.refreshGroups.get(ctx.refreshGroupId), + }; + }, + ); + const { rg } = res; + if (!rg) { + // Must've been deleted, we consider that final. + return true; + } + switch (rg.operationStatus) { + case RefreshOperationStatus.Failed: + case RefreshOperationStatus.Finished: + // Transaction is final + return true; + case RefreshOperationStatus.Pending: + case RefreshOperationStatus.Suspended: + break; + } + return false; + }, + filterNotification(notif): boolean { + return ( + notif.type === NotificationType.TransactionStateTransition && + notif.transactionId === ctx.transactionId + ); + }, }); - - try { - await internalWaitRefreshFinal(ctx, refreshNotifFlag); - } catch (e) { - unregisterOnCancelled(); - cancelNotif(); - } -} - -async function internalWaitRefreshFinal( - ctx: RefreshTransactionContext, - flag: AsyncFlag, -): Promise<void> { - while (true) { - if (ctx.wex.cancellationToken.isCancelled) { - throw Error("cancelled"); - } - - // Check if refresh is final - const res = await ctx.wex.db.runReadOnlyTx( - { storeNames: ["refreshGroups", "operationRetries"] }, - async (tx) => { - return { - rg: await tx.refreshGroups.get(ctx.refreshGroupId), - }; - }, - ); - const { rg } = res; - if (!rg) { - // Must've been deleted, we consider that final. - return; - } - switch (rg.operationStatus) { - case RefreshOperationStatus.Failed: - case RefreshOperationStatus.Finished: - // Transaction is final - return; - case RefreshOperationStatus.Pending: - case RefreshOperationStatus.Suspended: - break; - } - - // Wait for the next transition - await flag.wait(); - flag.reset(); - } } |