diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-12-11 18:49:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-11 18:49:26 +0100 |
commit | 65e72b68acf57da8462b8e7b057e7adb9393b698 (patch) | |
tree | 00e955e1186b9512b009acbb6ee80feb8a3f1733 /cli/worker.rs | |
parent | 9414dee9e56a9f42c07ada4f8e1be864a1a1b936 (diff) |
refactor(cli): decouple ops from ProgramState and Flags (#8659)
This commit does major refactor of "Worker" and "WebWorker",
in order to decouple them from "ProgramState" and "Flags".
The main points of interest are "create_main_worker()" and
"create_web_worker_callback()" functions which are responsible
for creating "Worker" and "WebWorker" in CLI context.
As a result it is now possible to factor out common "runtime"
functionality into a separate crate.
Diffstat (limited to 'cli/worker.rs')
-rw-r--r-- | cli/worker.rs | 184 |
1 files changed, 90 insertions, 94 deletions
diff --git a/cli/worker.rs b/cli/worker.rs index dda26291a..b119c3b0d 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -1,18 +1,19 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -use crate::fmt_errors::PrettyJsError; +use crate::colors; use crate::inspector::DenoInspector; +use crate::inspector::InspectorServer; use crate::inspector::InspectorSession; 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::version; use deno_core::error::AnyError; use deno_core::futures::future::poll_fn; use deno_core::futures::future::FutureExt; +use deno_core::serde_json; +use deno_core::serde_json::json; use deno_core::url::Url; use deno_core::JsErrorCreateFn; use deno_core::JsRuntime; @@ -35,68 +36,51 @@ use std::task::Poll; /// are descendants of this worker. pub struct MainWorker { inspector: Option<Box<DenoInspector>>, - js_runtime: JsRuntime, + pub js_runtime: JsRuntime, should_break_on_first_statement: bool, } -impl MainWorker { - pub fn new( - program_state: &Arc<ProgramState>, - main_module: ModuleSpecifier, - permissions: Permissions, - ) -> Self { - let module_loader = CliModuleLoader::new(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) - }); - - Self::from_options( - program_state, - main_module, - permissions, - module_loader, - Some(js_error_create_fn), - ) - } +pub struct WorkerOptions { + pub apply_source_maps: bool, + 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>, + // Callback that will be invoked when creating new instance + // of WebWorker + pub create_web_worker_cb: Arc<ops::worker_host::CreateWebWorkerCb>, + pub js_error_create_fn: Option<Rc<JsErrorCreateFn>>, + pub attach_inspector: bool, + pub maybe_inspector_server: Option<Arc<InspectorServer>>, + pub should_break_on_first_statement: bool, +} +impl MainWorker { pub fn from_options( - program_state: &Arc<ProgramState>, main_module: ModuleSpecifier, permissions: Permissions, - module_loader: Rc<dyn ModuleLoader>, - js_error_create_fn: Option<Box<JsErrorCreateFn>>, + options: &WorkerOptions, ) -> Self { - // TODO(bartlomieju): this is hacky way to not apply source - // maps in JS - let apply_source_maps = js_error_create_fn.is_some(); - 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, + 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 should_break_on_first_statement = - inspector.is_some() && program_state.flags.inspect_brk.is_some(); + inspector.is_some() && options.should_break_on_first_statement; let mut worker = Self { inspector, @@ -111,15 +95,21 @@ impl MainWorker { 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::runtime::init(js_runtime, main_module, apply_source_maps); - 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, None); - ops::crypto::init(js_runtime, program_state.flags.seed); + ops::worker_host::init( + js_runtime, + None, + options.create_web_worker_cb.clone(), + ); + ops::crypto::init(js_runtime, options.seed); 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( @@ -127,7 +117,6 @@ impl MainWorker { "op_domain_to_ascii", deno_web::op_domain_to_ascii, ); - ops::errors::init(js_runtime); ops::fs_events::init(js_runtime); ops::fs::init(js_runtime); ops::io::init(js_runtime); @@ -136,11 +125,10 @@ impl MainWorker { ops::permissions::init(js_runtime); ops::plugin::init(js_runtime); ops::process::init(js_runtime); - ops::runtime_compiler::init(js_runtime); ops::signal::init(js_runtime); ops::tls::init(js_runtime); ops::tty::init(js_runtime); - ops::websocket::init(js_runtime); + ops::websocket::init(js_runtime, options.ca_filepath.as_deref()); } { let op_state = js_runtime.op_state(); @@ -157,10 +145,32 @@ impl MainWorker { t.add("stderr", Box::new(stream)); } } + worker - .execute("bootstrap.mainRuntime()") + } + + pub fn bootstrap(&mut self, options: &WorkerOptions) { + 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 script = format!( + "bootstrap.mainRuntime({})", + serde_json::to_string_pretty(&runtime_options).unwrap() + ); + self + .execute(&script) .expect("Failed to execute bootstrap script"); - worker } /// Same as execute2() but the filename defaults to "$CWD/__anonymous__". @@ -231,23 +241,28 @@ impl Drop for MainWorker { #[cfg(test)] mod tests { use super::*; - use crate::flags::DenoSubcommand; - use crate::flags::Flags; - use crate::program_state::ProgramState; fn create_test_worker() -> MainWorker { let main_module = ModuleSpecifier::resolve_url_or_path("./hello.js").unwrap(); - let flags = Flags { - subcommand: DenoSubcommand::Run { - script: main_module.to_string(), - }, - ..Default::default() + let permissions = Permissions::default(); + + let options = WorkerOptions { + apply_source_maps: false, + args: vec![], + debug_flag: false, + unstable: false, + ca_filepath: None, + seed: None, + js_error_create_fn: None, + create_web_worker_cb: Arc::new(|_| unreachable!()), + attach_inspector: false, + maybe_inspector_server: None, + should_break_on_first_statement: false, + module_loader: Rc::new(deno_core::FsModuleLoader), }; - let permissions = Permissions::from_flags(&flags); - let program_state = - ProgramState::mock(vec!["deno".to_string()], Some(flags)); - MainWorker::new(&program_state, main_module, permissions) + + MainWorker::from_options(main_module, permissions, &options) } #[tokio::test] @@ -273,26 +288,7 @@ mod tests { let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) .parent() .unwrap() - .join("tests/circular1.ts"); - let module_specifier = - ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); - let mut worker = create_test_worker(); - let result = worker.execute_module(&module_specifier).await; - if let Err(err) = result { - eprintln!("execute_mod err {:?}", err); - } - if let Err(e) = worker.run_event_loop().await { - panic!("Future got unexpected error: {:?}", e); - } - } - - #[tokio::test] - async fn execute_006_url_imports() { - let _http_server_guard = test_util::http_server(); - let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .join("cli/tests/006_url_imports.ts"); + .join("tests/circular1.js"); let module_specifier = ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); let mut worker = create_test_worker(); @@ -323,7 +319,7 @@ mod tests { let p = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")) .parent() .unwrap() - .join("cli/tests/002_hello.ts"); + .join("cli/tests/001_hello.js"); let module_specifier = ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap(); let result = worker.execute_module(&module_specifier).await; |