summaryrefslogtreecommitdiff
path: root/cli/js/worker_main.ts
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-01-21 09:49:47 +0100
committerGitHub <noreply@github.com>2020-01-21 09:49:47 +0100
commit7966bf14c062a05b1606a62c996890571454ecc8 (patch)
tree65bede64b47707c3accc80d0bb18e99840c639f7 /cli/js/worker_main.ts
parentc90036ab88bb1ae6b9c87d5e368f56d8c8afab69 (diff)
refactor: split worker and worker host logic (#3722)
* split ops/worker.rs into ops/worker_host.rs and ops/web_worker.rs * refactor js/workers.ts and factor out js/worker_main.ts - entry point for WebWorker runtime * BREAKING CHANGE: remove support for blob: URL in Worker * BREAKING CHANGE: remove Deno namespace support and noDenoNamespace option in Worker constructor * introduce WebWorker struct which is a stripped down version of cli::Worker
Diffstat (limited to 'cli/js/worker_main.ts')
-rw-r--r--cli/js/worker_main.ts98
1 files changed, 98 insertions, 0 deletions
diff --git a/cli/js/worker_main.ts b/cli/js/worker_main.ts
new file mode 100644
index 000000000..cb70057ea
--- /dev/null
+++ b/cli/js/worker_main.ts
@@ -0,0 +1,98 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { core } from "./core.ts";
+import * as dispatch from "./dispatch.ts";
+import { sendAsync, sendSync } from "./dispatch_json.ts";
+import { log } from "./util.ts";
+import { TextDecoder, TextEncoder } from "./text_encoding.ts";
+
+const encoder = new TextEncoder();
+const decoder = new TextDecoder();
+
+function encodeMessage(data: any): Uint8Array {
+ const dataJson = JSON.stringify(data);
+ return encoder.encode(dataJson);
+}
+
+function decodeMessage(dataIntArray: Uint8Array): any {
+ const dataJson = decoder.decode(dataIntArray);
+ return JSON.parse(dataJson);
+}
+
+// Stuff for workers
+export const onmessage: (e: { data: any }) => void = (): void => {};
+export const onerror: (e: { data: any }) => void = (): void => {};
+
+export function postMessage(data: any): void {
+ const dataIntArray = encodeMessage(data);
+ sendSync(dispatch.OP_WORKER_POST_MESSAGE, {}, dataIntArray);
+}
+
+export async function getMessage(): Promise<any> {
+ log("getMessage");
+ const res = await sendAsync(dispatch.OP_WORKER_GET_MESSAGE);
+ if (res.data != null) {
+ return decodeMessage(new Uint8Array(res.data));
+ } else {
+ return null;
+ }
+}
+
+export let isClosing = false;
+
+export function workerClose(): void {
+ isClosing = true;
+}
+
+export async function workerMain(): Promise<void> {
+ const ops = core.ops();
+ // TODO(bartlomieju): this is a prototype, we should come up with
+ // something a bit more sophisticated
+ for (const [name, opId] of Object.entries(ops)) {
+ const opName = `OP_${name.toUpperCase()}`;
+ // Assign op ids to actual variables
+ // TODO(ry) This type casting is gross and should be fixed.
+ ((dispatch as unknown) as { [key: string]: number })[opName] = opId;
+ core.setAsyncHandler(opId, dispatch.getAsyncHandler(opName));
+ }
+
+ log("workerMain");
+
+ while (!isClosing) {
+ const data = await getMessage();
+ if (data == null) {
+ log("workerMain got null message. quitting.");
+ break;
+ }
+
+ let result: void | Promise<void>;
+ const event = { data };
+
+ try {
+ if (!globalThis["onmessage"]) {
+ break;
+ }
+ result = globalThis.onmessage!(event);
+ if (result && "then" in result) {
+ await result;
+ }
+ if (!globalThis["onmessage"]) {
+ break;
+ }
+ } catch (e) {
+ if (globalThis["onerror"]) {
+ const result = globalThis.onerror(
+ e.message,
+ e.fileName,
+ e.lineNumber,
+ e.columnNumber,
+ e
+ );
+ if (result === true) {
+ continue;
+ }
+ }
+ throw e;
+ }
+ }
+}