aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-core/src')
-rw-r--r--packages/taler-wallet-core/src/refresh.ts96
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();
- }
}