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:
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?.();