summaryrefslogtreecommitdiff
path: root/cli/web_worker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/web_worker.rs')
-rw-r--r--cli/web_worker.rs151
1 files changed, 99 insertions, 52 deletions
diff --git a/cli/web_worker.rs b/cli/web_worker.rs
index 44806d520..9320c22d8 100644
--- a/cli/web_worker.rs
+++ b/cli/web_worker.rs
@@ -1,28 +1,31 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::colors;
-use crate::fmt_errors::PrettyJsError;
use crate::inspector::DenoInspector;
+use crate::inspector::InspectorServer;
use crate::js;
use crate::metrics::Metrics;
-use crate::module_loader::CliModuleLoader;
use crate::ops;
use crate::permissions::Permissions;
-use crate::program_state::ProgramState;
-use crate::source_maps::apply_source_map;
use crate::tokio_util::create_basic_runtime;
+use crate::version;
use deno_core::error::AnyError;
use deno_core::futures::channel::mpsc;
use deno_core::futures::future::poll_fn;
use deno_core::futures::future::FutureExt;
use deno_core::futures::stream::StreamExt;
use deno_core::futures::task::AtomicWaker;
+use deno_core::serde_json;
+use deno_core::serde_json::json;
use deno_core::url::Url;
use deno_core::v8;
+use deno_core::JsErrorCreateFn;
use deno_core::JsRuntime;
+use deno_core::ModuleLoader;
use deno_core::ModuleSpecifier;
use deno_core::RuntimeOptions;
use std::env;
+use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::sync::Arc;
@@ -115,6 +118,7 @@ fn create_channels(
/// Each `WebWorker` is either a child of `MainWorker` or other
/// `WebWorker`.
pub struct WebWorker {
+ id: u32,
inspector: Option<Box<DenoInspector>>,
// Following fields are pub because they are accessed
// when creating a new WebWorker instance.
@@ -125,46 +129,48 @@ pub struct WebWorker {
event_loop_idle: bool,
terminate_rx: mpsc::Receiver<()>,
handle: WebWorkerHandle,
- pub has_deno_namespace: bool,
+ pub use_deno_namespace: bool,
+}
+
+pub struct WebWorkerOptions {
+ pub args: Vec<String>,
+ pub debug_flag: bool,
+ pub unstable: bool,
+ pub ca_filepath: Option<String>,
+ pub seed: Option<u64>,
+ pub module_loader: Rc<dyn ModuleLoader>,
+ pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>,
+ pub js_error_create_fn: Option<Rc<JsErrorCreateFn>>,
+ pub use_deno_namespace: bool,
+ pub attach_inspector: bool,
+ pub maybe_inspector_server: Option<Arc<InspectorServer>>,
+ pub apply_source_maps: bool,
}
impl WebWorker {
- pub fn new(
+ pub fn from_options(
name: String,
permissions: Permissions,
main_module: ModuleSpecifier,
- program_state: Arc<ProgramState>,
- has_deno_namespace: bool,
worker_id: u32,
+ options: &WebWorkerOptions,
) -> Self {
- let module_loader = CliModuleLoader::new_for_worker(program_state.clone());
- let global_state_ = program_state.clone();
-
- let js_error_create_fn = Box::new(move |core_js_error| {
- let source_mapped_error =
- apply_source_map(&core_js_error, global_state_.clone());
- PrettyJsError::create(source_mapped_error)
- });
-
let mut js_runtime = JsRuntime::new(RuntimeOptions {
- module_loader: Some(module_loader),
+ module_loader: Some(options.module_loader.clone()),
startup_snapshot: Some(js::deno_isolate_init()),
- js_error_create_fn: Some(js_error_create_fn),
+ js_error_create_fn: options.js_error_create_fn.clone(),
get_error_class_fn: Some(&crate::errors::get_error_class_name),
..Default::default()
});
- let inspector =
- if let Some(inspector_server) = &program_state.maybe_inspector_server {
- Some(DenoInspector::new(
- &mut js_runtime,
- Some(inspector_server.clone()),
- ))
- } else if program_state.flags.coverage || program_state.flags.repl {
- Some(DenoInspector::new(&mut js_runtime, None))
- } else {
- None
- };
+ let inspector = if options.attach_inspector {
+ Some(DenoInspector::new(
+ &mut js_runtime,
+ options.maybe_inspector_server.clone(),
+ ))
+ } else {
+ None
+ };
let (terminate_tx, terminate_rx) = mpsc::channel::<()>(1);
let isolate_handle = js_runtime.v8_isolate().thread_safe_handle();
@@ -172,15 +178,16 @@ impl WebWorker {
create_channels(isolate_handle, terminate_tx);
let mut worker = Self {
+ id: worker_id,
inspector,
internal_channels,
js_runtime,
- name: name.clone(),
+ name,
waker: AtomicWaker::new(),
event_loop_idle: false,
terminate_rx,
handle,
- has_deno_namespace,
+ use_deno_namespace: options.use_deno_namespace,
};
{
@@ -192,15 +199,21 @@ impl WebWorker {
let op_state = js_runtime.op_state();
let mut op_state = op_state.borrow_mut();
op_state.put::<Metrics>(Default::default());
- op_state.put::<Arc<ProgramState>>(program_state.clone());
op_state.put::<Permissions>(permissions);
+ op_state.put::<ops::UnstableChecker>(ops::UnstableChecker {
+ unstable: options.unstable,
+ });
}
ops::web_worker::init(js_runtime, sender.clone(), handle);
- ops::runtime::init(js_runtime, main_module, true);
- ops::fetch::init(js_runtime, program_state.flags.ca_file.as_deref());
+ ops::runtime::init(js_runtime, main_module);
+ ops::fetch::init(js_runtime, options.ca_filepath.as_deref());
ops::timers::init(js_runtime);
- ops::worker_host::init(js_runtime, Some(sender));
+ ops::worker_host::init(
+ js_runtime,
+ Some(sender),
+ options.create_web_worker_cb.clone(),
+ );
ops::reg_json_sync(js_runtime, "op_close", deno_core::op_close);
ops::reg_json_sync(js_runtime, "op_resources", deno_core::op_resources);
ops::reg_json_sync(
@@ -208,11 +221,10 @@ impl WebWorker {
"op_domain_to_ascii",
deno_web::op_domain_to_ascii,
);
- ops::errors::init(js_runtime);
ops::io::init(js_runtime);
- ops::websocket::init(js_runtime);
+ ops::websocket::init(js_runtime, options.ca_filepath.as_deref());
- if has_deno_namespace {
+ if options.use_deno_namespace {
ops::fs_events::init(js_runtime);
ops::fs::init(js_runtime);
ops::net::init(js_runtime);
@@ -220,8 +232,7 @@ impl WebWorker {
ops::permissions::init(js_runtime);
ops::plugin::init(js_runtime);
ops::process::init(js_runtime);
- ops::crypto::init(js_runtime, program_state.flags.seed);
- ops::runtime_compiler::init(js_runtime);
+ ops::crypto::init(js_runtime, options.seed);
ops::signal::init(js_runtime);
ops::tls::init(js_runtime);
ops::tty::init(js_runtime);
@@ -239,19 +250,38 @@ impl WebWorker {
op_state.resource_table.add("stderr", Box::new(stream));
}
}
+
+ worker
}
+ }
+
+ pub fn bootstrap(&mut self, options: &WebWorkerOptions) {
+ let runtime_options = json!({
+ "args": options.args,
+ "applySourceMaps": options.apply_source_maps,
+ "debugFlag": options.debug_flag,
+ "denoVersion": version::deno(),
+ "noColor": !colors::use_color(),
+ "pid": std::process::id(),
+ "ppid": ops::runtime::ppid(),
+ "target": env!("TARGET"),
+ "tsVersion": version::TYPESCRIPT,
+ "unstableFlag": options.unstable,
+ "v8Version": deno_core::v8_version(),
+ });
+
+ let runtime_options_str =
+ serde_json::to_string_pretty(&runtime_options).unwrap();
// 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-{}\")",
+ runtime_options_str, self.name, options.use_deno_namespace, self.id
);
- worker
+ self
.execute(&script)
.expect("Failed to execute worker bootstrap script");
-
- worker
}
/// Same as execute2() but the filename defaults to "$CWD/__anonymous__".
@@ -421,22 +451,39 @@ pub fn run_web_worker(
#[cfg(test)]
mod tests {
use super::*;
- use crate::program_state::ProgramState;
use crate::tokio_util;
use deno_core::serde_json::json;
fn create_test_web_worker() -> WebWorker {
let main_module =
ModuleSpecifier::resolve_url_or_path("./hello.js").unwrap();
- let program_state = ProgramState::mock(vec!["deno".to_string()], None);
- WebWorker::new(
+ let module_loader = Rc::new(deno_core::NoopModuleLoader);
+ let create_web_worker_cb = Arc::new(|_| unreachable!());
+
+ let options = WebWorkerOptions {
+ args: vec![],
+ apply_source_maps: false,
+ debug_flag: false,
+ unstable: false,
+ ca_filepath: None,
+ seed: None,
+ module_loader,
+ create_web_worker_cb,
+ js_error_create_fn: None,
+ use_deno_namespace: false,
+ attach_inspector: false,
+ maybe_inspector_server: None,
+ };
+
+ let mut worker = WebWorker::from_options(
"TEST".to_string(),
Permissions::allow_all(),
main_module,
- program_state,
- false,
1,
- )
+ &options,
+ );
+ worker.bootstrap(&options);
+ worker
}
#[tokio::test]