From a1e0fc3b88ed4305f942fadbea66b29a3934721c Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 16 Aug 2019 15:03:52 +0200 Subject: crypto worker refactoring --- src/crypto/synchronousWorker.ts | 122 +++++++++------------------------------- 1 file changed, 26 insertions(+), 96 deletions(-) (limited to 'src/crypto/synchronousWorker.ts') diff --git a/src/crypto/synchronousWorker.ts b/src/crypto/synchronousWorker.ts index 7d115f1dc..4369612ad 100644 --- a/src/crypto/synchronousWorker.ts +++ b/src/crypto/synchronousWorker.ts @@ -14,19 +14,37 @@ GNU Taler; see the file COPYING. If not, see */ -import { EmscEnvironment } from "./emscInterface"; import { CryptoImplementation } from "./cryptoImplementation"; +import { NodeEmscriptenLoader } from "./nodeEmscriptenLoader"; + import fs = require("fs"); +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"); + } + const workerCtor = require("./synchronousWorker").SynchronousCryptoWorker; + return new workerCtor(); + } + + getConcurrency(): number { + return 1; + } +} + /** * Worker implementation that uses node subprocesses. */ export class SynchronousCryptoWorker { - private cachedEmscEnvironment: EmscEnvironment | undefined = undefined; - private cachedEmscEnvironmentPromise: - | Promise - | undefined = undefined; /** * Function to be called when we receive a message from the worker thread. @@ -38,6 +56,8 @@ export class SynchronousCryptoWorker { */ onerror: undefined | ((m: any) => void); + private emscriptenLoader = new NodeEmscriptenLoader(); + constructor() { this.onerror = undefined; this.onmessage = undefined; @@ -57,96 +77,6 @@ export class SynchronousCryptoWorker { } } - private async getWasmBinary(): Promise { - // @ts-ignore - const akonoGetData = global.__akono_getData; - if (akonoGetData) { - // We're running embedded node on Android - console.log("reading wasm binary from akono"); - const data = akonoGetData("taler-emscripten-lib.wasm"); - // The data we get is base64-encoded binary data - let buf = new Buffer(data, 'base64'); - return new Uint8Array(buf); - - } else { - // We're in a normal node environment - const binaryPath = __dirname + "/../../../emscripten/taler-emscripten-lib.wasm"; - console.log("reading from", binaryPath); - const wasmBinary = new Uint8Array(fs.readFileSync(binaryPath)); - return wasmBinary; - } - } - - private async getEmscriptenEnvironment(): Promise { - if (this.cachedEmscEnvironment) { - return this.cachedEmscEnvironment; - } - - if (this.cachedEmscEnvironmentPromise) { - return this.cachedEmscEnvironmentPromise; - } - - let lib: any; - - const wasmBinary = await this.getWasmBinary(); - - return new Promise((resolve, reject) => { - // Arguments passed to the emscripten prelude - const libArgs = { - wasmBinary, - onRuntimeInitialized: () => { - if (!lib) { - console.error("fatal emscripten initialization error"); - return; - } - this.cachedEmscEnvironmentPromise = undefined; - this.cachedEmscEnvironment = new EmscEnvironment(lib); - resolve(this.cachedEmscEnvironment); - }, - }; - - // Make sure that TypeScript doesn't try - // to check the taler-emscripten-lib. - const indirectRequire = require; - - const g = global; - - // unavoidable hack, so that emscripten detects - // the environment as node even though importScripts - // is present. - - // @ts-ignore - const savedImportScripts = g.importScripts; - // @ts-ignore - delete g.importScripts; - // @ts-ignore - const savedCrypto = g.crypto; - // @ts-ignore - delete g.crypto; - - // Assume that the code is run from the build/ directory. - const libFn = indirectRequire( - "../../../emscripten/taler-emscripten-lib.js", - ); - lib = libFn(libArgs); - - // @ts-ignore - g.importScripts = savedImportScripts; - // @ts-ignore - g.crypto = savedCrypto; - - if (!lib) { - throw Error("could not load taler-emscripten-lib.js"); - } - - if (!lib.ccall) { - throw Error( - "sanity check failed: taler-emscripten lib does not have 'ccall'", - ); - } - }); - } - private dispatchMessage(msg: any) { if (this.onmessage) { this.onmessage({ data: msg }); @@ -154,7 +84,7 @@ export class SynchronousCryptoWorker { } private async handleRequest(operation: string, id: number, args: string[]) { - let emsc = await this.getEmscriptenEnvironment(); + let emsc = await this.emscriptenLoader.getEmscriptenEnvironment(); const impl = new CryptoImplementation(emsc); -- cgit v1.2.3