Skip to content

Commit

Permalink
chore(unstable): Enable Deno APIs by default in Workers
Browse files Browse the repository at this point in the history
  • Loading branch information
nayeemrmn committed Oct 29, 2020
1 parent 8d99adb commit 945df45
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 154 deletions.
46 changes: 0 additions & 46 deletions cli/dts/lib.deno.shared_globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -669,52 +669,6 @@ declare class Worker extends EventTarget {
options?: {
type?: "classic" | "module";
name?: string;
/** UNSTABLE: New API. Expect many changes; most likely this
* field will be made into an object for more granular
* configuration of worker thread (permissions, import map, etc.).
*
* Set to `true` to make `Deno` namespace and all of its methods
* available to worker thread.
*
* Currently worker inherits permissions from main thread (permissions
* given using `--allow-*` flags).
* Configurable permissions are on the roadmap to be implemented.
*
* Example:
*
* ```ts
* // mod.ts
* const worker = new Worker(
* new URL("deno_worker.ts", import.meta.url).href,
* { type: "module", deno: true }
* );
* worker.postMessage({ cmd: "readFile", fileName: "./log.txt" });
*
* // deno_worker.ts
*
*
* self.onmessage = async function (e) {
* const { cmd, fileName } = e.data;
* if (cmd !== "readFile") {
* throw new Error("Invalid command");
* }
* const buf = await Deno.readFile(fileName);
* const fileContents = new TextDecoder().decode(buf);
* console.log(fileContents);
* }
* ```
*
* // log.txt
* hello world
* hello world 2
*
* // run program
* $ deno run --allow-read mod.ts
* hello world
* hello world2
*
*/
deno?: boolean;
},
);
postMessage(message: any, transfer: ArrayBuffer[]): void;
Expand Down
48 changes: 16 additions & 32 deletions cli/ops/worker_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,36 +77,28 @@ fn create_web_worker(
program_state: &Arc<ProgramState>,
permissions: Permissions,
specifier: ModuleSpecifier,
has_deno_namespace: bool,
) -> Result<WebWorker, AnyError> {
let mut worker = WebWorker::new(
name.clone(),
permissions,
specifier,
program_state.clone(),
has_deno_namespace,
);

if has_deno_namespace {
let state = worker.js_runtime.op_state();
let mut state = state.borrow_mut();
let (stdin, stdout, stderr) = get_stdio();
if let Some(stream) = stdin {
state.resource_table.add("stdin", Box::new(stream));
}
if let Some(stream) = stdout {
state.resource_table.add("stdout", Box::new(stream));
}
if let Some(stream) = stderr {
state.resource_table.add("stderr", Box::new(stream));
}
let mut worker =
WebWorker::new(name.clone(), permissions, specifier, program_state.clone());

let state = worker.js_runtime.op_state();
let mut state = state.borrow_mut();
let (stdin, stdout, stderr) = get_stdio();
if let Some(stream) = stdin {
state.resource_table.add("stdin", Box::new(stream));
}
if let Some(stream) = stdout {
state.resource_table.add("stdout", Box::new(stream));
}
if let Some(stream) = stderr {
state.resource_table.add("stderr", Box::new(stream));
}

// Instead of using name for log we use `worker-${id}` because
// WebWorkers can have empty string as name.
let script = format!(
"bootstrap.workerRuntime(\"{}\", {}, \"worker-{}\")",
name, worker.has_deno_namespace, worker_id
"bootstrap.workerRuntime(\"{}\", \"worker-{}\")",
name, worker_id
);
worker.execute(&script)?;

Expand All @@ -120,7 +112,6 @@ fn run_worker_thread(
program_state: &Arc<ProgramState>,
permissions: Permissions,
specifier: ModuleSpecifier,
has_deno_namespace: bool,
maybe_source_code: Option<String>,
) -> Result<(JoinHandle<()>, WebWorkerHandle), AnyError> {
let program_state = program_state.clone();
Expand All @@ -140,7 +131,6 @@ fn run_worker_thread(
&program_state,
permissions,
specifier.clone(),
has_deno_namespace,
);

if let Err(err) = result {
Expand Down Expand Up @@ -221,7 +211,6 @@ struct CreateWorkerArgs {
specifier: String,
has_source_code: bool,
source_code: String,
use_deno_namespace: bool,
}

/// Create worker as the host
Expand All @@ -239,10 +228,6 @@ fn op_create_worker(
None
};
let args_name = args.name;
let use_deno_namespace = args.use_deno_namespace;
if use_deno_namespace {
super::check_unstable(state, "Worker.deno");
}
let permissions = state.borrow::<Permissions>().clone();
let worker_id = state.take::<WorkerId>();
state.put::<WorkerId>(worker_id + 1);
Expand All @@ -257,7 +242,6 @@ fn op_create_worker(
&cli_state,
permissions,
module_specifier,
use_deno_namespace,
maybe_source_code,
)?;
// At this point all interactions with worker happen using thread
Expand Down
5 changes: 0 additions & 5 deletions cli/rt/11_workers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@
specifier,
hasSourceCode,
sourceCode,
useDenoNamespace,
name,
) {
return core.jsonOpSync("op_create_worker", {
specifier,
hasSourceCode,
sourceCode,
name,
useDenoNamespace,
});
}

Expand Down Expand Up @@ -66,13 +64,10 @@
const hasSourceCode = false;
const sourceCode = decoder.decode(new Uint8Array());

const useDenoNamespace = options ? !!options.deno : false;

const { id } = createWorker(
specifier,
hasSourceCode,
sourceCode,
useDenoNamespace,
options?.name,
);
this.#id = id;
Expand Down
35 changes: 15 additions & 20 deletions cli/rt/99_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ delete Object.prototype.__proto__;
util.log("args", args);
}

function bootstrapWorkerRuntime(name, useDenoNamespace, internalName) {
function bootstrapWorkerRuntime(name, internalName) {
if (hasBootstrapped) {
throw new Error("Worker runtime already bootstrapped");
}
Expand Down Expand Up @@ -362,26 +362,21 @@ delete Object.prototype.__proto__;
close: core.close,
...denoNs,
};
if (useDenoNamespace) {
if (unstableFlag) {
Object.assign(finalDenoNs, denoNsUnstable);
}
Object.defineProperties(finalDenoNs, {
pid: util.readOnly(pid),
noColor: util.readOnly(noColor),
args: util.readOnly(Object.freeze(args)),
});
// Setup `Deno` global - we're actually overriding already
// existing global `Deno` with `Deno` namespace from "./deno.ts".
util.immutableDefine(globalThis, "Deno", finalDenoNs);
Object.freeze(globalThis.Deno);
Object.freeze(globalThis.Deno.core);
Object.freeze(globalThis.Deno.core.sharedQueue);
signals.setSignals();
} else {
delete globalThis.Deno;
util.assert(globalThis.Deno === undefined);
if (unstableFlag) {
Object.assign(finalDenoNs, denoNsUnstable);
}
Object.defineProperties(finalDenoNs, {
pid: util.readOnly(pid),
noColor: util.readOnly(noColor),
args: util.readOnly(Object.freeze(args)),
});
// Setup `Deno` global - we're actually overriding already
// existing global `Deno` with `Deno` namespace from "./deno.ts".
util.immutableDefine(globalThis, "Deno", finalDenoNs);
Object.freeze(globalThis.Deno);
Object.freeze(globalThis.Deno.core);
Object.freeze(globalThis.Deno.core.sharedQueue);
signals.setSignals();
}

Object.defineProperties(globalThis, {
Expand Down
4 changes: 2 additions & 2 deletions cli/tests/subdir/deno_worker.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
onmessage = function (e): void {
if (typeof self.Deno === "undefined") {
throw new Error("Deno namespace not available in worker");
if (Deno.inspect(1) == "1") {
throw new Error("Inspect didn't work.");
}

postMessage(e.data);
Expand Down
7 changes: 0 additions & 7 deletions cli/tests/subdir/non_deno_worker.js

This file was deleted.

24 changes: 4 additions & 20 deletions cli/tests/workers_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,36 +284,20 @@ Deno.test({
});

Deno.test({
name: "worker with Deno namespace",
name: "worker with Deno API",
fn: async function (): Promise<void> {
const promise = createResolvable();
const promise2 = createResolvable();

const regularWorker = new Worker(
new URL("subdir/non_deno_worker.js", import.meta.url).href,
{ type: "module" },
);
const denoWorker = new Worker(
new URL("subdir/deno_worker.ts", import.meta.url).href,
{ type: "module", deno: true },
{ type: "module" },
);

regularWorker.onmessage = (e): void => {
assertEquals(e.data, "Hello World");
regularWorker.terminate();
promise.resolve();
};

denoWorker.onmessage = (e): void => {
assertEquals(e.data, "Hello World");
denoWorker.terminate();
promise2.resolve();
promise.resolve();
};

regularWorker.postMessage("Hello World");
await promise;
denoWorker.postMessage("Hello World");
await promise2;
await promise;
},
});

Expand Down
35 changes: 13 additions & 22 deletions cli/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ pub struct WebWorker {
event_loop_idle: bool,
terminate_rx: mpsc::Receiver<()>,
handle: WebWorkerHandle,
pub has_deno_namespace: bool,
}

impl WebWorker {
Expand All @@ -401,7 +400,6 @@ impl WebWorker {
permissions: Permissions,
main_module: ModuleSpecifier,
program_state: Arc<ProgramState>,
has_deno_namespace: bool,
) -> Self {
let loader = CliModuleLoader::new_for_worker();
let mut worker = Worker::new(
Expand All @@ -428,7 +426,6 @@ impl WebWorker {
event_loop_idle: false,
terminate_rx,
handle,
has_deno_namespace,
};

{
Expand Down Expand Up @@ -459,21 +456,18 @@ impl WebWorker {
ops::errors::init(js_runtime);
ops::io::init(js_runtime);
ops::websocket::init(js_runtime);

if has_deno_namespace {
ops::fs_events::init(js_runtime);
ops::fs::init(js_runtime);
ops::net::init(js_runtime);
ops::os::init(js_runtime);
ops::permissions::init(js_runtime);
ops::plugin::init(js_runtime);
ops::process::init(js_runtime);
ops::random::init(js_runtime, program_state.flags.seed);
ops::runtime_compiler::init(js_runtime);
ops::signal::init(js_runtime);
ops::tls::init(js_runtime);
ops::tty::init(js_runtime);
}
ops::fs_events::init(js_runtime);
ops::fs::init(js_runtime);
ops::net::init(js_runtime);
ops::os::init(js_runtime);
ops::permissions::init(js_runtime);
ops::plugin::init(js_runtime);
ops::process::init(js_runtime);
ops::random::init(js_runtime, program_state.flags.seed);
ops::runtime_compiler::init(js_runtime);
ops::signal::init(js_runtime);
ops::tls::init(js_runtime);
ops::tty::init(js_runtime);
}

web_worker
Expand Down Expand Up @@ -694,11 +688,8 @@ mod tests {
Permissions::allow_all(),
main_module,
program_state,
false,
);
worker
.execute("bootstrap.workerRuntime(\"TEST\", false)")
.unwrap();
worker.execute("bootstrap.workerRuntime(\"TEST\")").unwrap();
worker
}
#[tokio::test]
Expand Down

0 comments on commit 945df45

Please sign in to comment.