taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit be382b2eabb840f0bfa48cee04206b7c888c0a45
parent edcf051016a25c2daba531ad3b47e0772bf6660b
Author: Florian Dold <dold@taler.net>
Date:   Thu, 20 Aug 2026 19:06:42 +0200

wallet-core: reject queued crypto work on shutdown

Diffstat:
Mpackages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts | 22++++++++++++++++++++++
Mpackages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts | 8++++++++
2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts @@ -193,3 +193,25 @@ test("a worker that does answer is not terminated", async (t) => { assert.ok((resp as any).testResult === 42); assert.strictEqual(factory.started[0].terminated, false); }); + +test("stopping the dispatcher rejects running and queued work", async () => { + const cryptoDisp = new CryptoDispatcher(new MyCryptoWorkerFactory()); + const running = cryptoDisp.doRpc("testTimeout", 0, {}); + const queued = cryptoDisp.doRpc("testSuccess", 0, {}); + const settled = Promise.allSettled([running, queued]); + + cryptoDisp.stop(); + + const timedOut = Symbol("timed out"); + const result = await Promise.race([ + settled, + new Promise<typeof timedOut>((resolve) => + setTimeout(() => resolve(timedOut), 20), + ), + ]); + assert.notStrictEqual(result, timedOut, "queued work remained unresolved"); + assert.deepStrictEqual( + (result as PromiseSettledResult<unknown>[]).map((x) => x.status), + ["rejected", "rejected"], + ); +}); diff --git a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts @@ -167,6 +167,7 @@ export class CryptoDispatcher { worker.idleTimeoutHandle = null; } if (worker.currentWorkItem) { + worker.currentWorkItem.state = WorkItemState.Finished; worker.currentWorkItem.reject(new CryptoApiStoppedError()); worker.currentWorkItem = null; } @@ -176,6 +177,13 @@ export class CryptoDispatcher { worker.w = null; } } + this.numBusy = 0; + for (const queue of this.workQueues) { + for (const workItem of queue.splice(0)) { + workItem.state = WorkItemState.Finished; + workItem.reject(new CryptoApiStoppedError()); + } + } } stop(): void {