taler-typescript-core

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

commit 8e7a3f7583c5cb259e96fa4dce8ebe3095dfaa38
parent febffad71b6218071c293595ae6911ef6772b093
Author: Florian Dold <dold@taler.net>
Date:   Fri, 28 Aug 2026 17:02:14 +0200

wallet-core: cancel queued database imports

Diffstat:
Mpackages/taler-wallet-core/src/wallet-db-gate.test.ts | 28++++++++++++++++++++++++++++
Mpackages/taler-wallet-core/src/wallet.ts | 2+-
2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/packages/taler-wallet-core/src/wallet-db-gate.test.ts b/packages/taler-wallet-core/src/wallet-db-gate.test.ts @@ -146,6 +146,34 @@ test("cross-backend database import has exclusive admission", async () => { assert.deepStrictEqual(events, ["cross-import", "db:tx", "after"]); }); +test("cross-backend database import can be cancelled while waiting", async () => { + const events: string[] = []; + const gate = new DbOperationGate(); + const handle = fakeHandle("db", events); + handle.importAnyDatabase = async () => { + assert.fail("cancelled cross-backend import was admitted"); + }; + const admitted = new AdmittedWalletDbHandle(() => handle, gate); + const active = deferred(); + const releaseActive = deferred(); + const blocker = admitted.runReadWriteTx(async () => { + active.resolve(); + await releaseActive.promise; + }); + await active.promise; + + const cts = CancellationToken.create(); + const importing = admitted.importAnyDatabase!({}, async () => {}, { + cancellationToken: cts.token, + }); + await Promise.resolve(); + cts.cancel(); + await assert.rejects(importing, CancellationToken.CancellationError); + + releaseActive.resolve(); + await blocker; +}); + test("database gate cancels an exclusive waiter", async () => { const gate = new DbOperationGate(); const active = deferred(); diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts @@ -262,7 +262,7 @@ export class AdmittedWalletDbHandle implements WalletDbHandle { "current database backend cannot import a foreign dump", ); return await fn.apply(db, args); - }); + }, args[2]?.cancellationToken); } if (current().getDiagnosticStats) { this.getDiagnosticStats = () => current().getDiagnosticStats?.();