From ffd2a62c3f7df94365980302fef3bc3376b48182 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 3 Aug 2020 13:00:48 +0530 Subject: modularize repo, use pnpm, improve typechecking --- .../src/crypto/workers/synchronousWorker.ts | 136 +++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts (limited to 'packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts') diff --git a/packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts b/packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts new file mode 100644 index 000000000..5327670bd --- /dev/null +++ b/packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts @@ -0,0 +1,136 @@ +/* + This file is part of GNU Taler + (C) 2019 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 + */ + +import { CryptoImplementation } from "./cryptoImplementation"; + +import { CryptoWorkerFactory } from "./cryptoApi"; +import { CryptoWorker } from "./cryptoWorker"; + +/** + * The synchronous crypto worker produced by this factory doesn't run in the + * background, but actually blocks the caller until the operation is done. + */ +export class SynchronousCryptoWorkerFactory implements CryptoWorkerFactory { + startWorker(): CryptoWorker { + if (typeof require === "undefined") { + throw Error("cannot make worker, require(...) not defined"); + } + return new SynchronousCryptoWorker(); + } + + getConcurrency(): number { + return 1; + } +} + +/** + * Worker implementation that uses node subprocesses. + */ +export class SynchronousCryptoWorker { + /** + * Function to be called when we receive a message from the worker thread. + */ + onmessage: undefined | ((m: any) => void); + + /** + * Function to be called when we receive an error from the worker thread. + */ + onerror: undefined | ((m: any) => void); + + constructor() { + this.onerror = undefined; + this.onmessage = 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({ data: msg }); + } + } + + private async handleRequest( + operation: string, + id: number, + args: string[], + ): Promise { + const impl = new CryptoImplementation(); + + if (!(operation in impl)) { + console.error(`crypto operation '${operation}' not found`); + return; + } + + let result: any; + try { + result = (impl as any)[operation](...args); + } catch (e) { + console.log("error during operation", e); + return; + } + + try { + setTimeout(() => this.dispatchMessage({ result, id }), 0); + } catch (e) { + console.log("got error during dispatch", e); + } + } + + /** + * Send a message to the worker thread. + */ + postMessage(msg: any): void { + const args = msg.args; + if (!Array.isArray(args)) { + console.error("args must be array"); + return; + } + const id = msg.id; + if (typeof id !== "number") { + console.error("RPC id must be number"); + return; + } + const operation = msg.operation; + if (typeof operation !== "string") { + console.error("RPC operation must be string"); + return; + } + + this.handleRequest(operation, id, args).catch((e) => { + console.error("Error while handling crypto request:", e); + }); + } + + /** + * Forcibly terminate the worker thread. + */ + terminate(): void { + // This is a no-op. + } +} -- cgit v1.2.3