commit 76a4547e15e6ee68b7650ce4768fb4e375e5257e
parent bdda23f77ba14b291ce49b26928b71100e62790c
Author: Florian Dold <florian@dold.me>
Date: Mon, 28 Oct 2024 11:49:57 +0100
wallet-core: simplify waiting for order download using helper
Diffstat:
1 file changed, 33 insertions(+), 52 deletions(-)
diff --git a/packages/taler-wallet-core/src/pay-merchant.ts b/packages/taler-wallet-core/src/pay-merchant.ts
@@ -114,6 +114,7 @@ import {
} from "./coinSelection.js";
import {
constructTaskIdentifier,
+ genericWaitForState,
PendingTaskType,
spendCoins,
TaskIdentifiers,
@@ -1832,59 +1833,39 @@ async function waitProposalDownloaded(
wex.taskScheduler.startShepherdTask(ctx.taskId);
- // FIXME: We should use Symbol.dispose magic here for cleanup!
-
- const payNotifFlag = new AsyncFlag();
- // Raise exchangeNotifFlag whenever we get a notification
- // about our exchange.
- const cancelNotif = wex.ws.addNotificationListener((notif) => {
- if (
- notif.type === NotificationType.TransactionStateTransition &&
- notif.transactionId === ctx.transactionId
- ) {
- logger.info(`raising update notification: ${j2s(notif)}`);
- payNotifFlag.raise();
- }
- });
-
- try {
- await internalWaitProposalDownloaded(ctx, payNotifFlag);
- logger.info(`done waiting for ${ctx.transactionId} to be downloaded`);
- } finally {
- cancelNotif();
- }
-}
-
-async function internalWaitProposalDownloaded(
- ctx: PayMerchantTransactionContext,
- payNotifFlag: AsyncFlag,
-): Promise<void> {
- while (true) {
- const { purchase, retryInfo } = await ctx.wex.db.runReadOnlyTx(
- { storeNames: ["purchases", "operationRetries"] },
- async (tx) => {
- return {
- purchase: await tx.purchases.get(ctx.proposalId),
- retryInfo: await tx.operationRetries.get(ctx.taskId),
- };
- },
- );
- if (!purchase) {
- throw Error("purchase does not exist anymore");
- }
- if (purchase.download) {
- return;
- }
- if (retryInfo) {
- if (retryInfo.lastError) {
- throw TalerError.fromUncheckedDetail(retryInfo.lastError);
- } else {
- throw Error("transient error while waiting for proposal download");
+ await genericWaitForState(wex, {
+ filterNotification(notif) {
+ return (
+ notif.type === NotificationType.TransactionStateTransition &&
+ notif.transactionId === ctx.transactionId
+ );
+ },
+ async checkState() {
+ const { purchase, retryInfo } = await ctx.wex.db.runReadOnlyTx(
+ { storeNames: ["purchases", "operationRetries"] },
+ async (tx) => {
+ return {
+ purchase: await tx.purchases.get(ctx.proposalId),
+ retryInfo: await tx.operationRetries.get(ctx.taskId),
+ };
+ },
+ );
+ if (!purchase) {
+ throw Error("purchase does not exist anymore");
}
- }
- await payNotifFlag.wait();
- payNotifFlag.reset();
- }
+ if (purchase.download) {
+ return true;
+ }
+ if (retryInfo) {
+ if (retryInfo.lastError) {
+ throw TalerError.fromUncheckedDetail(retryInfo.lastError);
+ } else {
+ throw Error("transient error while waiting for proposal download");
+ }
+ }
+ return false;
+ },
+ });
}
async function downloadTemplate(