summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/wallet.ts
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-06-22 13:52:28 +0200
committerFlorian Dold <florian@dold.me>2021-06-22 13:52:28 +0200
commite35c2f581b49f6441b6f75bb9ce0a1677d5fb46f (patch)
tree1e94c19f47e6f4461977a5d2ee536439092acbb2 /packages/taler-wallet-core/src/wallet.ts
parent7383b89cabbfdb8f2fbd6bb9e7b64d09385f7bea (diff)
downloadwallet-core-e35c2f581b49f6441b6f75bb9ce0a1677d5fb46f.tar.gz
wallet-core-e35c2f581b49f6441b6f75bb9ce0a1677d5fb46f.tar.bz2
wallet-core-e35c2f581b49f6441b6f75bb9ce0a1677d5fb46f.zip
simplify task loop, test coin suspension
Diffstat (limited to 'packages/taler-wallet-core/src/wallet.ts')
-rw-r--r--packages/taler-wallet-core/src/wallet.ts120
1 files changed, 40 insertions, 80 deletions
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts
index 6a7ee9de1..de0675cd6 100644
--- a/packages/taler-wallet-core/src/wallet.ts
+++ b/packages/taler-wallet-core/src/wallet.ts
@@ -276,81 +276,31 @@ export async function runPending(
}
}
-/**
- * Run the wallet until there are no more pending operations that give
- * liveness left. The wallet will be in a stopped state when this function
- * returns without resolving to an exception.
- */
-export async function runUntilDone(
- ws: InternalWalletState,
- req: {
- maxRetries?: number;
- } = {},
-): Promise<void> {
- let done = false;
- const p = new Promise<void>((resolve, reject) => {
- // Monitor for conditions that means we're done or we
- // should quit with an error (due to exceeded retries).
- ws.addNotificationListener((n) => {
- if (done) {
- return;
- }
- if (
- n.type === NotificationType.WaitingForRetry &&
- n.numGivingLiveness == 0
- ) {
- done = true;
- logger.trace("no liveness-giving operations left");
- resolve();
- }
- const maxRetries = req.maxRetries;
- if (!maxRetries) {
- return;
- }
- getPendingOperations(ws)
- .then((pending) => {
- for (const p of pending.pendingOperations) {
- if (p.retryInfo && p.retryInfo.retryCounter > maxRetries) {
- console.warn(
- `stopping, as ${maxRetries} retries are exceeded in an operation of type ${p.type}`,
- );
- ws.stop();
- done = true;
- resolve();
- }
- }
- })
- .catch((e) => {
- logger.error(e);
- reject(e);
- });
- });
- // Run this asynchronously
- runRetryLoop(ws).catch((e) => {
- logger.error("exception in wallet retry loop");
- reject(e);
- });
- });
- await p;
+export interface RetryLoopOpts {
+ /**
+ * Stop when the number of retries is exceeded for any pending
+ * operation.
+ */
+ maxRetries?: number;
+
+ /**
+ * Stop the retry loop when all lifeness-giving pending operations
+ * are done.
+ *
+ * Defaults to false.
+ */
+ stopWhenDone?: boolean;
}
/**
- * Process pending operations and wait for scheduled operations in
- * a loop until the wallet is stopped explicitly.
+ * Main retry loop of the wallet.
+ *
+ * Looks up pending operations from the wallet, runs them, repeat.
*/
-export async function runRetryLoop(ws: InternalWalletState): Promise<void> {
- // Make sure we only run one main loop at a time.
- return ws.memoRunRetryLoop.memo(async () => {
- try {
- await runRetryLoopImpl(ws);
- } catch (e) {
- console.error("error during retry loop execution", e);
- throw e;
- }
- });
-}
-
-async function runRetryLoopImpl(ws: InternalWalletState): Promise<void> {
+async function runTaskLoop(
+ ws: InternalWalletState,
+ opts: RetryLoopOpts = {},
+): Promise<void> {
for (let iteration = 0; !ws.stopped; iteration++) {
const pending = await getPendingOperations(ws);
logger.trace(`pending operations: ${j2s(pending)}`);
@@ -365,7 +315,22 @@ async function runRetryLoopImpl(ws: InternalWalletState): Promise<void> {
if (p.givesLifeness) {
numGivingLiveness++;
}
+
+ const maxRetries = opts.maxRetries;
+
+ if (maxRetries && p.retryInfo && p.retryInfo.retryCounter > maxRetries) {
+ logger.warn(
+ `stopping, as ${maxRetries} retries are exceeded in an operation of type ${p.type}`,
+ );
+ return;
+ }
}
+
+ if (opts.stopWhenDone && numGivingLiveness === 0) {
+ logger.warn(`stopping, as no pending operations have lifeness`);
+ return;
+ }
+
// Make sure that we run tasks that don't give lifeness at least
// one time.
if (iteration !== 0 && numDue === 0) {
@@ -993,19 +958,15 @@ export class Wallet {
}
runRetryLoop(): Promise<void> {
- return runRetryLoop(this.ws);
+ return runTaskLoop(this.ws);
}
runPending(forceNow: boolean = false) {
return runPending(this.ws, forceNow);
}
- runUntilDone(
- req: {
- maxRetries?: number;
- } = {},
- ) {
- return runUntilDone(this.ws, req);
+ runTaskLoop(opts: RetryLoopOpts) {
+ return runTaskLoop(this.ws, opts);
}
handleCoreApiRequest(
@@ -1035,7 +996,6 @@ class InternalWalletStateImpl implements InternalWalletState {
timerGroup: TimerGroup = new TimerGroup();
latch = new AsyncCondition();
stopped = false;
- memoRunRetryLoop = new AsyncOpMemoSingle<void>();
listeners: NotificationListener[] = [];
@@ -1102,7 +1062,7 @@ class InternalWalletStateImpl implements InternalWalletState {
maxRetries?: number;
} = {},
): Promise<void> {
- runUntilDone(this, req);
+ await runTaskLoop(this, { ...req, stopWhenDone: true });
}
/**