From 2fa0096821cd04334210fcae6f54f85d304dc17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 11 Feb 2022 13:41:56 +0100 Subject: compat: support --compat in web workers (#13629) Adds another callback to WebWorkerOptions that allows to execute some modules before actual worker code executes. This allows to set up Node global using std/node. --- runtime/ops/worker_host.rs | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'runtime/ops/worker_host.rs') diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs index c241e9a54..1213da6d2 100644 --- a/runtime/ops/worker_host.rs +++ b/runtime/ops/worker_host.rs @@ -12,6 +12,7 @@ use crate::web_worker::WebWorkerType; use crate::web_worker::WorkerControlEvent; use crate::web_worker::WorkerId; use deno_core::error::AnyError; +use deno_core::futures::future::LocalFutureObj; use deno_core::op_async; use deno_core::op_sync; use deno_core::serde::Deserialize; @@ -42,13 +43,24 @@ pub type CreateWebWorkerCb = dyn Fn(CreateWebWorkerArgs) -> (WebWorker, Sendable + Sync + Send; +pub type PreloadModuleCb = dyn Fn(WebWorker) -> LocalFutureObj<'static, Result> + + Sync + + Send; + /// A holder for callback that is used to create a new /// WebWorker. It's a struct instead of a type alias /// because `GothamState` used in `OpState` overrides -/// value if type alises have the same underlying type +/// value if type aliases have the same underlying type #[derive(Clone)] pub struct CreateWebWorkerCbHolder(Arc); +/// A holder for callback that can used to preload some modules into a WebWorker +/// before actual worker code is executed. It's a struct instead of a type +/// because `GothamState` used in `OpState` overrides +/// value if type aliases have the same underlying type +#[derive(Clone)] +pub struct PreloadModuleCbHolder(Arc); + pub struct WorkerThread { // It's an Option so we can take the value before dropping the WorkerThread. join_handle: Option>>, @@ -91,15 +103,21 @@ impl Drop for WorkerThread { pub type WorkersTable = HashMap; -pub fn init(create_web_worker_cb: Arc) -> Extension { +pub fn init( + create_web_worker_cb: Arc, + preload_module_cb: Arc, +) -> Extension { Extension::builder() .state(move |state| { state.put::(WorkersTable::default()); state.put::(WorkerId::default()); - let create_module_loader = + let create_web_worker_cb_holder = CreateWebWorkerCbHolder(create_web_worker_cb.clone()); - state.put::(create_module_loader); + state.put::(create_web_worker_cb_holder); + let preload_module_cb_holder = + PreloadModuleCbHolder(preload_module_cb.clone()); + state.put::(preload_module_cb_holder); Ok(()) }) @@ -174,8 +192,10 @@ fn op_create_worker( // have access to `exit_code` but the child does? let maybe_exit_code = state.try_borrow::>().cloned(); let worker_id = state.take::(); - let create_module_loader = state.take::(); - state.put::(create_module_loader.clone()); + let create_web_worker_cb = state.take::(); + state.put::(create_web_worker_cb.clone()); + let preload_module_cb = state.take::(); + state.put::(preload_module_cb.clone()); state.put::(worker_id.next().unwrap()); let module_specifier = deno_core::resolve_url(&specifier)?; @@ -197,7 +217,7 @@ fn op_create_worker( // - newly spawned thread exits let (worker, external_handle) = - (create_module_loader.0)(CreateWebWorkerArgs { + (create_web_worker_cb.0)(CreateWebWorkerArgs { name: worker_name, worker_id, parent_permissions, @@ -216,7 +236,12 @@ fn op_create_worker( // is using `worker.internal_channels`. // // Host can already push messages and interact with worker. - run_web_worker(worker, module_specifier, maybe_source_code) + run_web_worker( + worker, + module_specifier, + maybe_source_code, + preload_module_cb.0, + ) })?; // Receive WebWorkerHandle from newly created worker -- cgit v1.2.3