From 60374078f4e41e9398607628d8b33b74bb3431aa Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 4 Jan 2023 13:24:19 +0100 Subject: wallet-core: test crypto dispatcher, fix timeout handling --- .../src/crypto/workers/crypto-dispatcher.test.ts | 130 +++++++ .../src/crypto/workers/crypto-dispatcher.ts | 382 ++++++++++++++++++++ .../src/crypto/workers/cryptoDispatcher.ts | 386 --------------------- .../src/crypto/workers/nodeThreadWorker.ts | 2 +- .../crypto/workers/synchronousWorkerFactoryNode.ts | 2 +- .../workers/synchronousWorkerFactoryPlain.ts | 2 +- packages/taler-wallet-core/src/index.ts | 2 +- .../taler-wallet-core/src/internal-wallet-state.ts | 2 +- .../taler-wallet-core/src/operations/refresh.ts | 2 +- packages/taler-wallet-core/src/wallet.ts | 2 +- 10 files changed, 519 insertions(+), 393 deletions(-) create mode 100644 packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts create mode 100644 packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts delete mode 100644 packages/taler-wallet-core/src/crypto/workers/cryptoDispatcher.ts (limited to 'packages/taler-wallet-core') 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 new file mode 100644 index 000000000..b63c9bf11 --- /dev/null +++ b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts @@ -0,0 +1,130 @@ +/* + This file is part of GNU Taler + (C) 2023 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import test from "ava"; +import { CryptoDispatcher, CryptoWorkerFactory } from "./crypto-dispatcher.js"; +import { CryptoWorker, CryptoWorkerResponseMessage } from "./cryptoWorkerInterface.js"; +import { SynchronousCryptoWorkerFactoryNode } from "./synchronousWorkerFactoryNode.js"; +import { processRequestWithImpl } from "./worker-common.js"; + + +export class MyCryptoWorker implements CryptoWorker { + /** + * Function to be called when we receive a message from the worker thread. + */ + onmessage: undefined | ((m: any) => void) = undefined; + + /** + * Function to be called when we receive an error from the worker thread. + */ + onerror: undefined | ((m: any) => void) = undefined; + + /** + * Add an event listener for either an "error" or "message" event. + */ + addEventListener(event: "message" | "error", fn: (x: any) => void): void { + switch (event) { + case "message": + this.onmessage = fn; + break; + case "error": + this.onerror = fn; + break; + } + } + + private dispatchMessage(msg: any): void { + if (this.onmessage) { + this.onmessage(msg); + } + } + + /** + * Send a message to the worker thread. + */ + postMessage(msg: any): void { + const handleRequest = async () => { + let responseMsg: CryptoWorkerResponseMessage; + if (msg.operation === "testSuccess") { + responseMsg = { + id: msg.id, + type: "success", + result: { + testResult: 42, + } + } + } else if (msg.operation === "testError") { + responseMsg = { + id: msg.id, + type: "error", + error: { + code: 42, + hint: "bla", + } + } + } else if (msg.operation === "testTimeout") { + // Don't respond + return; + } + try { + setTimeout(() => this.dispatchMessage(responseMsg), 0); + } catch (e) { + console.error("got error during dispatch", e); + } + }; + handleRequest().catch((e) => { + console.error("Error while handling crypto request:", e); + }); + } + + /** + * Forcibly terminate the worker thread. + */ + terminate(): void { + // This is a no-op. + } +} + + + +export class MyCryptoWorkerFactory implements CryptoWorkerFactory { + startWorker(): CryptoWorker { + return new MyCryptoWorker(); + } + + getConcurrency(): number { + return 1; + } +} + +test("continues after error", async (t) => { + const cryptoDisp = new CryptoDispatcher( + new MyCryptoWorkerFactory(), + ); + const resp1 = await cryptoDisp.doRpc("testSuccess", 0, {}); + t.assert((resp1 as any).testResult === 42); + const exc = await t.throwsAsync(async() => { + const resp2 = await cryptoDisp.doRpc("testError", 0, {}); + }); + + // Check that it still works after one error. + const resp2 = await cryptoDisp.doRpc("testSuccess", 0, {}); + t.assert((resp2 as any).testResult === 42); + + // Check that it still works after timeout. + const resp3 = await cryptoDisp.doRpc("testSuccess", 0, {}); + t.assert((resp3 as any).testResult === 42); +}); diff --git a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts new file mode 100644 index 000000000..940078ea6 --- /dev/null +++ b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.ts @@ -0,0 +1,382 @@ +/* + This file is part of GNU Taler + (C) 2016 GNUnet e.V. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * API to access the Taler crypto worker. + * + * @author Florian Dold + */ + +/** + * Imports. + */ +import { j2s, Logger, TalerErrorCode } from "@gnu-taler/taler-util"; +import { TalerError } from "../../errors.js"; +import { openPromise } from "../../util/promiseUtils.js"; +import { timer, performanceNow, TimerHandle } from "../../util/timer.js"; +import { nullCrypto, TalerCryptoInterface } from "../cryptoImplementation.js"; +import { CryptoWorker } from "./cryptoWorkerInterface.js"; + +const logger = new Logger("cryptoDispatcher.ts"); + +/** + * State of a crypto worker. + */ +interface WorkerInfo { + /** + * The actual worker thread. + */ + w: CryptoWorker | null; + + /** + * Work we're currently executing or null if not busy. + */ + currentWorkItem: WorkItem | null; + + /** + * Timer to terminate the worker if it's not busy enough. + */ + idleTimeoutHandle: TimerHandle | null; +} + +interface WorkItem { + operation: string; + req: unknown; + resolve: any; + reject: any; + + /** + * Serial id to identify a matching response. + */ + rpcId: number; + + /** + * Time when the work was submitted to a (non-busy) worker thread. + */ + startTime: BigInt; + + state: WorkItemState; +} + +/** + * Number of different priorities. Each priority p + * must be 0 <= p < NUM_PRIO. + */ +const NUM_PRIO = 5; + +/** + * A crypto worker factory is responsible for creating new + * crypto workers on-demand. + */ +export interface CryptoWorkerFactory { + /** + * Start a new worker. + */ + startWorker(): CryptoWorker; + + /** + * Query the number of workers that should be + * run at the same time. + */ + getConcurrency(): number; +} + +export class CryptoApiStoppedError extends Error { + constructor() { + super("Crypto API stopped"); + Object.setPrototypeOf(this, CryptoApiStoppedError.prototype); + } +} + +export enum WorkItemState { + Pending = 1, + Running = 2, + Finished = 3, +} + +/** + * Dispatcher for cryptographic operations to underlying crypto workers. + */ +export class CryptoDispatcher { + private nextRpcId = 1; + private workers: WorkerInfo[]; + private workQueues: WorkItem[][]; + + private workerFactory: CryptoWorkerFactory; + + /** + * Number of busy workers. + */ + private numBusy = 0; + + /** + * Did we stop accepting new requests? + */ + private stopped = false; + + /** + * Terminate all worker threads. + */ + terminateWorkers(): void { + for (const worker of this.workers) { + if (worker.idleTimeoutHandle) { + worker.idleTimeoutHandle.clear(); + worker.idleTimeoutHandle = null; + } + if (worker.currentWorkItem) { + worker.currentWorkItem.reject(new CryptoApiStoppedError()); + worker.currentWorkItem = null; + } + if (worker.w) { + logger.trace("terminating worker"); + worker.w.terminate(); + worker.w = null; + } + } + } + + stop(): void { + this.stopped = true; + this.terminateWorkers(); + } + + /** + * Start a worker (if not started) and set as busy. + */ + wake(ws: WorkerInfo, work: WorkItem): void { + if (this.stopped) { + return; + } + if (ws.currentWorkItem !== null) { + throw Error("assertion failed"); + } + ws.currentWorkItem = work; + this.numBusy++; + let worker: CryptoWorker; + if (!ws.w) { + worker = this.workerFactory.startWorker(); + worker.onmessage = (m: any) => this.handleWorkerMessage(ws, m); + worker.onerror = (e: any) => this.handleWorkerError(ws, e); + ws.w = worker; + } else { + worker = ws.w; + } + + const msg: any = { + req: work.req, + id: work.rpcId, + operation: work.operation, + }; + this.resetWorkerTimeout(ws); + work.startTime = performanceNow(); + work.state = WorkItemState.Running; + timer.after(0, () => worker.postMessage(msg)); + } + + resetWorkerTimeout(ws: WorkerInfo): void { + if (ws.idleTimeoutHandle !== null) { + ws.idleTimeoutHandle.clear(); + ws.idleTimeoutHandle = null; + } + const destroy = (): void => { + logger.trace("destroying crypto worker after idle timeout"); + // terminate worker if it's idle + if (ws.w && ws.currentWorkItem === null) { + ws.w.terminate(); + ws.w = null; + } + }; + ws.idleTimeoutHandle = timer.after(15 * 1000, destroy); + ws.idleTimeoutHandle.unref(); + } + + private resetWorker(ws: WorkerInfo, e: any): void { + try { + if (ws.w) { + ws.w.terminate(); + ws.w = null; + } + } catch (e) { + logger.error(e as string); + } + if (ws.currentWorkItem !== null) { + ws.currentWorkItem.state = WorkItemState.Finished; + ws.currentWorkItem.reject(e); + ws.currentWorkItem = null; + this.numBusy--; + } + this.findWork(ws); + } + + handleWorkerError(ws: WorkerInfo, e: any): void { + if (ws.currentWorkItem) { + logger.error(`error in worker during ${ws.currentWorkItem.operation}`, e); + } else { + logger.error("error in worker", e); + } + logger.error(e.message); + this.resetWorker(ws, e); + } + + private findWork(ws: WorkerInfo): void { + // try to find more work for this worker + for (let i = 0; i < NUM_PRIO; i++) { + const q = this.workQueues[NUM_PRIO - i - 1]; + if (q.length !== 0) { + const work: WorkItem | undefined = q.shift(); + if (!work) { + continue; + } + this.wake(ws, work); + return; + } + } + } + + handleWorkerMessage(ws: WorkerInfo, msg: any): void { + const id = msg.id; + if (typeof id !== "number") { + logger.error("rpc id must be number"); + return; + } + const currentWorkItem = ws.currentWorkItem; + ws.currentWorkItem = null; + if (!currentWorkItem) { + logger.error("unsolicited response from worker"); + return; + } + if (id !== currentWorkItem.rpcId) { + logger.error(`RPC with id ${id} has no registry entry`); + return; + } + if (currentWorkItem.state === WorkItemState.Running) { + this.numBusy--; + currentWorkItem.state = WorkItemState.Finished; + if (msg.type === "success") { + currentWorkItem.resolve(msg.result); + } else if (msg.type === "error") { + currentWorkItem.reject( + TalerError.fromDetail(TalerErrorCode.WALLET_CRYPTO_WORKER_ERROR, { + innerError: msg.error, + }), + ); + } else { + logger.warn(`bad message: ${j2s(msg)}`); + currentWorkItem.reject(new Error("bad message from crypto worker")); + } + } + this.findWork(ws); + } + + cryptoApi: TalerCryptoInterface; + + constructor(workerFactory: CryptoWorkerFactory) { + const fns: any = {}; + for (const name of Object.keys(nullCrypto)) { + fns[name] = (x: any) => this.doRpc(name, 0, x); + } + + this.cryptoApi = fns; + + this.workerFactory = workerFactory; + this.workers = new Array(workerFactory.getConcurrency()); + + for (let i = 0; i < this.workers.length; i++) { + this.workers[i] = { + currentWorkItem: null, + idleTimeoutHandle: null, + w: null, + }; + } + + this.workQueues = []; + for (let i = 0; i < NUM_PRIO; i++) { + this.workQueues.push([]); + } + } + + doRpc( + operation: string, + priority: number, + req: unknown, + ): Promise { + if (this.stopped) { + throw new CryptoApiStoppedError(); + } + const rpcId = this.nextRpcId++; + const myProm = openPromise(); + const workItem: WorkItem = { + operation, + req, + resolve: myProm.resolve, + reject: myProm.reject, + rpcId, + startTime: BigInt(0), + state: WorkItemState.Pending, + }; + let scheduled = false; + if (this.numBusy === this.workers.length) { + // All workers are busy, queue work item + const q = this.workQueues[priority]; + if (!q) { + throw Error("assertion failed"); + } + this.workQueues[priority].push(workItem); + scheduled = true; + } + if (!scheduled) { + for (const ws of this.workers) { + if (ws.currentWorkItem !== null) { + continue; + } + this.wake(ws, workItem); + scheduled = true; + break; + } + } + + if (!scheduled) { + // Could not schedule work. + throw Error("assertion failed"); + } + + // Make sure that we wait for the result while a timer is active + // to prevent the event loop from dying, as just waiting for a promise + // does not keep the process alive in Node. + // (The worker child process won't keep us alive either, because we un-ref + // it to make sure it doesn't keep us alive if there is no work.) + return new Promise((resolve, reject) => { + let timeoutHandle: TimerHandle | undefined = undefined; + const timeoutMs = 5000; + const onTimeout = () => { + // FIXME: Maybe destroy and re-init worker if request is in processing + // state and really taking too long? + logger.warn(`crypto RPC call ('${operation}') has been queued for a long time`); + timeoutHandle = timer.after(timeoutMs, onTimeout); + }; + myProm.promise + .then((x) => { + timeoutHandle?.clear(); + resolve(x); + }) + .catch((x) => { + logger.info(`crypto RPC call ${operation} threw`); + timeoutHandle?.clear(); + reject(x); + }); + }); + } +} diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoDispatcher.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoDispatcher.ts deleted file mode 100644 index 88aea71b9..000000000 --- a/packages/taler-wallet-core/src/crypto/workers/cryptoDispatcher.ts +++ /dev/null @@ -1,386 +0,0 @@ -/* - This file is part of GNU Taler - (C) 2016 GNUnet e.V. - - GNU Taler is free software; you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation; either version 3, or (at your option) any later version. - - GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along with - GNU Taler; see the file COPYING. If not, see - */ - -/** - * API to access the Taler crypto worker. - * - * @author Florian Dold - */ - -/** - * Imports. - */ -import { j2s, Logger, TalerErrorCode } from "@gnu-taler/taler-util"; -import { TalerError } from "../../errors.js"; -import { openPromise } from "../../util/promiseUtils.js"; -import { timer, performanceNow, TimerHandle } from "../../util/timer.js"; -import { nullCrypto, TalerCryptoInterface } from "../cryptoImplementation.js"; -import { CryptoWorker } from "./cryptoWorkerInterface.js"; - -const logger = new Logger("cryptoDispatcher.ts"); - -/** - * State of a crypto worker. - */ -interface WorkerInfo { - /** - * The actual worker thread. - */ - w: CryptoWorker | null; - - /** - * Work we're currently executing or null if not busy. - */ - currentWorkItem: WorkItem | null; - - /** - * Timer to terminate the worker if it's not busy enough. - */ - idleTimeoutHandle: TimerHandle | null; -} - -interface WorkItem { - operation: string; - req: unknown; - resolve: any; - reject: any; - - /** - * Serial id to identify a matching response. - */ - rpcId: number; - - /** - * Time when the work was submitted to a (non-busy) worker thread. - */ - startTime: BigInt; - - state: WorkItemState; -} - -/** - * Number of different priorities. Each priority p - * must be 0 <= p < NUM_PRIO. - */ -const NUM_PRIO = 5; - -/** - * A crypto worker factory is responsible for creating new - * crypto workers on-demand. - */ -export interface CryptoWorkerFactory { - /** - * Start a new worker. - */ - startWorker(): CryptoWorker; - - /** - * Query the number of workers that should be - * run at the same time. - */ - getConcurrency(): number; -} - -export class CryptoApiStoppedError extends Error { - constructor() { - super("Crypto API stopped"); - Object.setPrototypeOf(this, CryptoApiStoppedError.prototype); - } -} - -export enum WorkItemState { - Pending = 1, - Running = 2, - Finished = 3, -} - -/** - * Dispatcher for cryptographic operations to underlying crypto workers. - */ -export class CryptoDispatcher { - private nextRpcId = 1; - private workers: WorkerInfo[]; - private workQueues: WorkItem[][]; - - private workerFactory: CryptoWorkerFactory; - - /** - * Number of busy workers. - */ - private numBusy = 0; - - /** - * Did we stop accepting new requests? - */ - private stopped = false; - - /** - * Terminate all worker threads. - */ - terminateWorkers(): void { - for (const worker of this.workers) { - if (worker.idleTimeoutHandle) { - worker.idleTimeoutHandle.clear(); - worker.idleTimeoutHandle = null; - } - if (worker.currentWorkItem) { - worker.currentWorkItem.reject(new CryptoApiStoppedError()); - worker.currentWorkItem = null; - } - if (worker.w) { - logger.trace("terminating worker"); - worker.w.terminate(); - worker.w = null; - } - } - } - - stop(): void { - this.stopped = true; - this.terminateWorkers(); - } - - /** - * Start a worker (if not started) and set as busy. - */ - wake(ws: WorkerInfo, work: WorkItem): void { - if (this.stopped) { - return; - } - if (ws.currentWorkItem !== null) { - throw Error("assertion failed"); - } - ws.currentWorkItem = work; - this.numBusy++; - let worker: CryptoWorker; - if (!ws.w) { - worker = this.workerFactory.startWorker(); - worker.onmessage = (m: any) => this.handleWorkerMessage(ws, m); - worker.onerror = (e: any) => this.handleWorkerError(ws, e); - ws.w = worker; - } else { - worker = ws.w; - } - - const msg: any = { - req: work.req, - id: work.rpcId, - operation: work.operation, - }; - this.resetWorkerTimeout(ws); - work.startTime = performanceNow(); - work.state = WorkItemState.Running; - timer.after(0, () => worker.postMessage(msg)); - } - - resetWorkerTimeout(ws: WorkerInfo): void { - if (ws.idleTimeoutHandle !== null) { - ws.idleTimeoutHandle.clear(); - ws.idleTimeoutHandle = null; - } - const destroy = (): void => { - logger.trace("destroying crypto worker after idle timeout"); - // terminate worker if it's idle - if (ws.w && ws.currentWorkItem === null) { - ws.w.terminate(); - ws.w = null; - } - }; - ws.idleTimeoutHandle = timer.after(15 * 1000, destroy); - ws.idleTimeoutHandle.unref(); - } - - handleWorkerError(ws: WorkerInfo, e: any): void { - if (ws.currentWorkItem) { - logger.error(`error in worker during ${ws.currentWorkItem.operation}`, e); - } else { - logger.error("error in worker", e); - } - logger.error(e.message); - try { - if (ws.w) { - ws.w.terminate(); - ws.w = null; - } - } catch (e) { - logger.error(e as string); - } - if (ws.currentWorkItem !== null) { - ws.currentWorkItem.state = WorkItemState.Finished; - ws.currentWorkItem.reject(e); - ws.currentWorkItem = null; - this.numBusy--; - } - this.findWork(ws); - } - - private findWork(ws: WorkerInfo): void { - // try to find more work for this worker - for (let i = 0; i < NUM_PRIO; i++) { - const q = this.workQueues[NUM_PRIO - i - 1]; - if (q.length !== 0) { - const work: WorkItem | undefined = q.shift(); - if (!work) { - continue; - } - this.wake(ws, work); - return; - } - } - } - - handleWorkerMessage(ws: WorkerInfo, msg: any): void { - const id = msg.id; - if (typeof id !== "number") { - logger.error("rpc id must be number"); - return; - } - const currentWorkItem = ws.currentWorkItem; - ws.currentWorkItem = null; - if (!currentWorkItem) { - logger.error("unsolicited response from worker"); - return; - } - if (id !== currentWorkItem.rpcId) { - logger.error(`RPC with id ${id} has no registry entry`); - return; - } - if (currentWorkItem.state === WorkItemState.Running) { - this.numBusy--; - currentWorkItem.state = WorkItemState.Finished; - if (msg.type === "success") { - currentWorkItem.resolve(msg.result); - } else if (msg.type === "error") { - currentWorkItem.reject( - TalerError.fromDetail(TalerErrorCode.WALLET_CRYPTO_WORKER_ERROR, { - innerError: msg.error, - }), - ); - } else { - logger.warn(`bad message: ${j2s(msg)}`); - currentWorkItem.reject(new Error("bad message from crypto worker")); - } - } - this.findWork(ws); - } - - cryptoApi: TalerCryptoInterface; - - constructor(workerFactory: CryptoWorkerFactory) { - const fns: any = {}; - for (const name of Object.keys(nullCrypto)) { - fns[name] = (x: any) => this.doRpc(name, 0, x); - } - - this.cryptoApi = fns; - - this.workerFactory = workerFactory; - this.workers = new Array(workerFactory.getConcurrency()); - - for (let i = 0; i < this.workers.length; i++) { - this.workers[i] = { - currentWorkItem: null, - idleTimeoutHandle: null, - w: null, - }; - } - - this.workQueues = []; - for (let i = 0; i < NUM_PRIO; i++) { - this.workQueues.push([]); - } - } - - private doRpc( - operation: string, - priority: number, - req: unknown, - ): Promise { - if (this.stopped) { - throw new CryptoApiStoppedError(); - } - const rpcId = this.nextRpcId++; - const myProm = openPromise(); - const workItem: WorkItem = { - operation, - req, - resolve: myProm.resolve, - reject: myProm.reject, - rpcId, - startTime: BigInt(0), - state: WorkItemState.Pending, - }; - let scheduled = false; - if (this.numBusy === this.workers.length) { - // All workers are busy, queue work item - const q = this.workQueues[priority]; - if (!q) { - throw Error("assertion failed"); - } - this.workQueues[priority].push(workItem); - scheduled = true; - } - if (!scheduled) { - for (const ws of this.workers) { - if (ws.currentWorkItem !== null) { - continue; - } - this.wake(ws, workItem); - scheduled = true; - break; - } - } - - if (!scheduled) { - // Could not schedule work. - throw Error("assertion failed"); - } - - // Make sure that we wait for the result while a timer is active - // to prevent the event loop from dying, as just waiting for a promise - // does not keep the process alive in Node. - // (The worker child process won't keep us alive either, because we un-ref - // it to make sure it doesn't keep us alive if there is no work.) - return new Promise((resolve, reject) => { - let timedOut = false; - const timeout = timer.after(10000, () => { - logger.warn(`crypto RPC call ('${operation}') timed out`); - timedOut = true; - reject(new Error(`crypto RPC call ('${operation}') timed out`)); - if (workItem.state === WorkItemState.Running) { - workItem.state = WorkItemState.Finished; - this.numBusy--; - } - }); - myProm.promise - .then((x) => { - if (timedOut) { - return; - } - timeout.clear(); - resolve(x); - }) - .catch((x) => { - logger.info(`crypto RPC call ${operation} threw`); - if (timedOut) { - return; - } - timeout.clear(); - reject(x); - }); - }); - } -} diff --git a/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts b/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts index 634c891b6..db8bb4737 100644 --- a/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts +++ b/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts @@ -21,7 +21,7 @@ import { Logger } from "@gnu-taler/taler-util"; import os from "os"; import url from "url"; import { nativeCryptoR } from "../cryptoImplementation.js"; -import { CryptoWorkerFactory } from "./cryptoDispatcher.js"; +import { CryptoWorkerFactory } from "./crypto-dispatcher.js"; import { CryptoWorker } from "./cryptoWorkerInterface.js"; import { processRequestWithImpl } from "./worker-common.js"; diff --git a/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryNode.ts b/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryNode.ts index 46cf12915..90f9a43fa 100644 --- a/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryNode.ts +++ b/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryNode.ts @@ -17,7 +17,7 @@ /** * Imports. */ -import { CryptoWorkerFactory } from "./cryptoDispatcher.js"; +import { CryptoWorkerFactory } from "./crypto-dispatcher.js"; import { CryptoWorker } from "./cryptoWorkerInterface.js"; import { SynchronousCryptoWorkerNode } from "./synchronousWorkerNode.js"; diff --git a/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryPlain.ts b/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryPlain.ts index d0c8e4b3a..66381bc0e 100644 --- a/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryPlain.ts +++ b/packages/taler-wallet-core/src/crypto/workers/synchronousWorkerFactoryPlain.ts @@ -17,7 +17,7 @@ /** * Imports. */ -import { CryptoWorkerFactory } from "./cryptoDispatcher.js"; +import { CryptoWorkerFactory } from "./crypto-dispatcher.js"; import { CryptoWorker } from "./cryptoWorkerInterface.js"; import { SynchronousCryptoWorkerPlain } from "./synchronousWorkerPlain.js"; diff --git a/packages/taler-wallet-core/src/index.ts b/packages/taler-wallet-core/src/index.ts index 7cc23aa88..e48c9430f 100644 --- a/packages/taler-wallet-core/src/index.ts +++ b/packages/taler-wallet-core/src/index.ts @@ -37,7 +37,7 @@ export type { CryptoWorker } from "./crypto/workers/cryptoWorkerInterface.js"; export { CryptoWorkerFactory, CryptoDispatcher, -} from "./crypto/workers/cryptoDispatcher.js"; +} from "./crypto/workers/crypto-dispatcher.js"; export * from "./pending-types.js"; diff --git a/packages/taler-wallet-core/src/internal-wallet-state.ts b/packages/taler-wallet-core/src/internal-wallet-state.ts index ebb9cdb9b..93d813cc9 100644 --- a/packages/taler-wallet-core/src/internal-wallet-state.ts +++ b/packages/taler-wallet-core/src/internal-wallet-state.ts @@ -41,7 +41,7 @@ import { CoinRefreshRequest, RefreshReason, } from "@gnu-taler/taler-util"; -import { CryptoDispatcher } from "./crypto/workers/cryptoDispatcher.js"; +import { CryptoDispatcher } from "./crypto/workers/crypto-dispatcher.js"; import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; import { ExchangeDetailsRecord, ExchangeRecord, WalletStoresV1 } from "./db.js"; import { PendingOperationsResponse } from "./pending-types.js"; diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index 806e4a246..eeff84be6 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -52,7 +52,7 @@ import { DerivedRefreshSession, RefreshNewDenomInfo, } from "../crypto/cryptoTypes.js"; -import { CryptoApiStoppedError } from "../crypto/workers/cryptoDispatcher.js"; +import { CryptoApiStoppedError } from "../crypto/workers/crypto-dispatcher.js"; import { CoinRecord, CoinSourceType, diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index f442e678a..1defff0d2 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -106,7 +106,7 @@ import { TalerCryptoInterface } from "./crypto/cryptoImplementation.js"; import { CryptoDispatcher, CryptoWorkerFactory, -} from "./crypto/workers/cryptoDispatcher.js"; +} from "./crypto/workers/crypto-dispatcher.js"; import { clearDatabase } from "./db-utils.js"; import { AuditorTrustRecord, -- cgit v1.2.3