Provide option to delete Deno namespace in worker (#2717)

This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2019-08-05 04:23:41 -07:00 committed by Ryan Dahl
parent aaa7a3eac4
commit ddee2dff14
18 changed files with 128 additions and 17 deletions

View file

@ -25,7 +25,7 @@ const console = new Console(core.print);
window.console = console;
window.workerMain = workerMain;
export default function denoMain(): void {
os.start("TS");
os.start(true, "TS");
}
const ASSETS = "$asset$";

View file

@ -1,4 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { window } from "./window";
// This allows us to access core in API even if we
// dispose window.Deno
export const core = window.Deno.core as DenoCore;

View file

@ -32,7 +32,6 @@ import * as request from "./request";
// These imports are not exposed and therefore are fine to just import the
// symbols required.
import { core } from "./core";
import { immutableDefine } from "./util";
// During the build process, augmentations to the variable `window` in this
// file are tracked and created as part of default library that is built into
@ -71,7 +70,7 @@ window.window = window;
// This is the Deno namespace, it is handled differently from other window
// properties when building the runtime type library, as the whole module
// is flattened into a single namespace.
immutableDefine(window, "Deno", deno);
window.Deno = deno;
Object.freeze(window.Deno);
// Globally available functions and object instances.

View file

@ -18,8 +18,11 @@ import { setLocation } from "./location";
// builtin modules
import * as deno from "./deno";
export default function denoMain(name?: string): void {
const startResMsg = os.start(name);
export default function denoMain(
preserveDenoNamespace: boolean = true,
name?: string
): void {
const startResMsg = os.start(preserveDenoNamespace, name);
setVersions(startResMsg.denoVersion()!, startResMsg.v8Version()!);

View file

@ -112,7 +112,10 @@ function sendStart(): msg.StartRes {
// This function bootstraps an environment within Deno, it is shared both by
// the runtime and the compiler environments.
// @internal
export function start(source?: string): msg.StartRes {
export function start(
preserveDenoNamespace = true,
source?: string
): msg.StartRes {
core.setAsyncHandler(handleAsyncMsgFromRust);
// First we send an empty `Start` message to let the privileged side know we
@ -124,9 +127,18 @@ export function start(source?: string): msg.StartRes {
setGlobals(startResMsg.pid(), startResMsg.noColor(), startResMsg.execPath()!);
// Deno.core could ONLY be safely frozen here (not in globals.ts)
// since shared_queue.js will modify core properties.
Object.freeze(window.Deno.core);
if (preserveDenoNamespace) {
util.immutableDefine(window, "Deno", window.Deno);
// Deno.core could ONLY be safely frozen here (not in globals.ts)
// since shared_queue.js will modify core properties.
Object.freeze(window.Deno.core);
// core.sharedQueue is an object so we should also freeze it.
Object.freeze(window.Deno.core.sharedQueue);
} else {
// Remove window.Deno
delete window.Deno;
assert(window.Deno === undefined);
}
return startResMsg;
}

View file

@ -20,10 +20,17 @@ export function decodeMessage(dataIntArray: Uint8Array): any {
return JSON.parse(dataJson);
}
function createWorker(specifier: string): number {
function createWorker(
specifier: string,
includeDenoNamespace: boolean
): number {
const builder = flatbuffers.createBuilder();
const specifier_ = builder.createString(specifier);
const inner = msg.CreateWorker.createCreateWorker(builder, specifier_);
const inner = msg.CreateWorker.createCreateWorker(
builder,
specifier_,
includeDenoNamespace
);
const baseRes = sendSync(builder, msg.Any.CreateWorker, inner);
assert(baseRes != null);
assert(
@ -149,6 +156,18 @@ export interface Worker {
closed: Promise<void>;
}
// TODO(kevinkassimo): Maybe implement reasonable web worker options?
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface WorkerOptions {}
/** Extended Deno Worker initialization options.
* `noDenoNamespace` hides global `window.Deno` namespace for
* spawned worker and nested workers spawned by it (default: false).
*/
export interface DenoWorkerOptions extends WorkerOptions {
noDenoNamespace?: boolean;
}
export class WorkerImpl implements Worker {
private readonly rid: number;
private isClosing: boolean = false;
@ -157,8 +176,12 @@ export class WorkerImpl implements Worker {
public onmessage?: (data: any) => void;
public onmessageerror?: () => void;
constructor(specifier: string) {
this.rid = createWorker(specifier);
constructor(specifier: string, options?: DenoWorkerOptions) {
let includeDenoNamespace = true;
if (options && options.noDenoNamespace) {
includeDenoNamespace = false;
}
this.rid = createWorker(specifier, includeDenoNamespace);
this.run();
this.isClosedPromise = hostGetWorkerClosed(this.rid);
this.isClosedPromise.then(