2024-01-01 14:58:21 -05:00
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2020-11-26 09:17:45 -05:00
use crate ::colors ;
2021-05-26 15:07:12 -04:00
use crate ::inspector_server ::InspectorServer ;
2020-11-26 09:17:45 -05:00
use crate ::ops ;
2023-01-07 11:25:34 -05:00
use crate ::permissions ::PermissionsContainer ;
2023-08-28 17:30:46 -04:00
use crate ::shared ::runtime ;
2023-05-14 17:40:01 -04:00
use crate ::tokio_util ::create_and_run_current_thread ;
2023-12-28 14:37:10 -05:00
use crate ::worker ::import_meta_resolve_callback ;
2022-04-26 19:06:10 -04:00
use crate ::worker ::FormatJsErrorFn ;
2021-10-05 16:41:14 -04:00
use crate ::BootstrapOptions ;
2021-05-22 12:08:24 -04:00
use deno_broadcast_channel ::InMemoryBroadcastChannel ;
2022-09-28 08:11:12 -04:00
use deno_cache ::CreateCache ;
use deno_cache ::SqliteBackedCache ;
2023-04-04 08:46:31 -04:00
use deno_core ::ascii_str ;
2020-11-26 09:17:45 -05:00
use deno_core ::error ::AnyError ;
2021-06-22 10:30:16 -04:00
use deno_core ::error ::JsError ;
2020-11-26 09:17:45 -05:00
use deno_core ::futures ::channel ::mpsc ;
use deno_core ::futures ::future ::poll_fn ;
use deno_core ::futures ::stream ::StreamExt ;
2021-11-29 07:37:44 -05:00
use deno_core ::futures ::task ::AtomicWaker ;
2022-11-28 06:47:25 -05:00
use deno_core ::located_script_name ;
2021-05-11 15:09:09 -04:00
use deno_core ::serde ::Deserialize ;
use deno_core ::serde ::Serialize ;
2020-12-11 12:49:26 -05:00
use deno_core ::serde_json ::json ;
2020-11-26 09:17:45 -05:00
use deno_core ::v8 ;
2021-06-22 10:30:16 -04:00
use deno_core ::CancelHandle ;
2021-09-29 04:47:24 -04:00
use deno_core ::CompiledWasmModuleStore ;
2021-04-28 12:41:50 -04:00
use deno_core ::Extension ;
2023-10-12 11:55:50 -04:00
use deno_core ::FeatureChecker ;
2020-12-13 13:45:53 -05:00
use deno_core ::GetErrorClassFn ;
2020-11-26 09:17:45 -05:00
use deno_core ::JsRuntime ;
2024-01-09 23:18:40 -05:00
use deno_core ::ModuleCodeString ;
2021-05-11 15:09:09 -04:00
use deno_core ::ModuleId ;
2020-12-11 12:49:26 -05:00
use deno_core ::ModuleLoader ;
2020-11-26 09:17:45 -05:00
use deno_core ::ModuleSpecifier ;
2023-11-05 16:27:36 -05:00
use deno_core ::OpMetricsSummaryTracker ;
2023-11-26 18:09:04 -05:00
use deno_core ::PollEventLoopOptions ;
2020-11-26 09:17:45 -05:00
use deno_core ::RuntimeOptions ;
2021-07-06 13:42:52 -04:00
use deno_core ::SharedArrayBufferStore ;
2022-11-28 06:47:25 -05:00
use deno_core ::Snapshot ;
2022-04-15 10:08:09 -04:00
use deno_core ::SourceMapGetter ;
2023-11-01 14:57:55 -04:00
use deno_cron ::local ::LocalCronHandler ;
2023-05-04 14:28:42 -04:00
use deno_fs ::FileSystem ;
2023-05-10 10:23:26 -04:00
use deno_http ::DefaultHttpPropertyExtractor ;
2023-03-04 19:39:48 -05:00
use deno_io ::Stdio ;
2023-08-22 01:56:00 -04:00
use deno_kv ::dynamic ::MultiBackendDbHandler ;
2023-05-01 16:42:05 -04:00
use deno_tls ::RootCertStoreProvider ;
2021-06-22 10:30:16 -04:00
use deno_web ::create_entangled_message_port ;
2021-07-05 09:34:37 -04:00
use deno_web ::BlobStore ;
2021-06-22 10:30:16 -04:00
use deno_web ::MessagePort ;
2021-03-26 12:34:25 -04:00
use log ::debug ;
2021-05-11 15:09:09 -04:00
use std ::cell ::RefCell ;
use std ::fmt ;
2020-12-11 12:49:26 -05:00
use std ::rc ::Rc ;
2020-11-26 09:17:45 -05:00
use std ::sync ::atomic ::AtomicBool ;
use std ::sync ::atomic ::Ordering ;
use std ::sync ::Arc ;
use std ::task ::Context ;
use std ::task ::Poll ;
2021-08-16 08:29:54 -04:00
#[ derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize) ]
#[ serde(rename_all = " lowercase " ) ]
pub enum WebWorkerType {
Classic ,
Module ,
}
2021-05-11 15:09:09 -04:00
#[ derive(
Debug , Default , Copy , Clone , PartialEq , Eq , Hash , Serialize , Deserialize ,
) ]
pub struct WorkerId ( u32 ) ;
impl fmt ::Display for WorkerId {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
write! ( f , " worker-{} " , self . 0 )
}
}
impl WorkerId {
pub fn next ( & self ) -> Option < WorkerId > {
self . 0. checked_add ( 1 ) . map ( WorkerId )
}
}
2020-11-26 09:17:45 -05:00
/// Events that are sent to host from child
/// worker.
2021-06-22 10:30:16 -04:00
pub enum WorkerControlEvent {
2020-11-26 09:17:45 -05:00
Error ( AnyError ) ,
TerminalError ( AnyError ) ,
2021-05-11 15:09:09 -04:00
Close ,
2020-11-26 09:17:45 -05:00
}
2021-06-22 10:30:16 -04:00
use deno_core ::serde ::Serializer ;
impl Serialize for WorkerControlEvent {
fn serialize < S > ( & self , serializer : S ) -> Result < S ::Ok , S ::Error >
where
S : Serializer ,
{
let type_id = match & self {
WorkerControlEvent ::TerminalError ( _ ) = > 1_ i32 ,
WorkerControlEvent ::Error ( _ ) = > 2_ i32 ,
WorkerControlEvent ::Close = > 3_ i32 ,
} ;
match self {
WorkerControlEvent ::TerminalError ( error )
| WorkerControlEvent ::Error ( error ) = > {
let value = match error . downcast_ref ::< JsError > ( ) {
2022-04-15 10:08:09 -04:00
Some ( js_error ) = > {
2022-04-26 19:06:10 -04:00
let frame = js_error . frames . iter ( ) . find ( | f | match & f . file_name {
2023-03-08 06:44:54 -05:00
Some ( s ) = > ! s . trim_start_matches ( '[' ) . starts_with ( " ext: " ) ,
2022-04-26 19:06:10 -04:00
None = > false ,
} ) ;
2022-04-15 10:08:09 -04:00
json! ( {
" message " : js_error . exception_message ,
" fileName " : frame . map ( | f | f . file_name . as_ref ( ) ) ,
" lineNumber " : frame . map ( | f | f . line_number . as_ref ( ) ) ,
" columnNumber " : frame . map ( | f | f . column_number . as_ref ( ) ) ,
} )
}
2021-06-22 10:30:16 -04:00
None = > json! ( {
" message " : error . to_string ( ) ,
} ) ,
} ;
Serialize ::serialize ( & ( type_id , value ) , serializer )
}
_ = > Serialize ::serialize ( & ( type_id , ( ) ) , serializer ) ,
}
}
}
2021-05-11 15:09:09 -04:00
// Channels used for communication with worker's parent
#[ derive(Clone) ]
pub struct WebWorkerInternalHandle {
2021-06-22 10:30:16 -04:00
sender : mpsc ::Sender < WorkerControlEvent > ,
pub port : Rc < MessagePort > ,
pub cancel : Rc < CancelHandle > ,
2021-11-29 07:37:44 -05:00
termination_signal : Arc < AtomicBool > ,
has_terminated : Arc < AtomicBool > ,
terminate_waker : Arc < AtomicWaker > ,
2021-05-11 15:09:09 -04:00
isolate_handle : v8 ::IsolateHandle ,
2022-04-13 05:50:57 -04:00
pub name : String ,
2021-08-16 08:29:54 -04:00
pub worker_type : WebWorkerType ,
2021-05-11 15:09:09 -04:00
}
impl WebWorkerInternalHandle {
/// Post WorkerEvent to parent as a worker
2021-06-22 10:30:16 -04:00
pub fn post_event ( & self , event : WorkerControlEvent ) -> Result < ( ) , AnyError > {
2021-05-11 15:09:09 -04:00
let mut sender = self . sender . clone ( ) ;
// If the channel is closed,
// the worker must have terminated but the termination message has not yet been received.
//
// Therefore just treat it as if the worker has terminated and return.
if sender . is_closed ( ) {
2021-11-29 07:37:44 -05:00
self . has_terminated . store ( true , Ordering ::SeqCst ) ;
2021-05-11 15:09:09 -04:00
return Ok ( ( ) ) ;
}
sender . try_send ( event ) ? ;
Ok ( ( ) )
}
/// Check if this worker is terminated or being terminated
pub fn is_terminated ( & self ) -> bool {
2021-11-29 07:37:44 -05:00
self . has_terminated . load ( Ordering ::SeqCst )
}
/// Check if this worker must terminate (because the termination signal is
/// set), and terminates it if so. Returns whether the worker is terminated or
/// being terminated, as with [`Self::is_terminated()`].
pub fn terminate_if_needed ( & mut self ) -> bool {
let has_terminated = self . is_terminated ( ) ;
if ! has_terminated & & self . termination_signal . load ( Ordering ::SeqCst ) {
self . terminate ( ) ;
return true ;
}
has_terminated
2021-05-11 15:09:09 -04:00
}
/// Terminate the worker
/// This function will set terminated to true, terminate the isolate and close the message channel
pub fn terminate ( & mut self ) {
2021-06-22 10:30:16 -04:00
self . cancel . cancel ( ) ;
2023-12-06 19:02:52 -05:00
self . terminate_waker . wake ( ) ;
2021-06-22 10:30:16 -04:00
2021-05-11 15:09:09 -04:00
// This function can be called multiple times by whomever holds
// the handle. However only a single "termination" should occur so
// we need a guard here.
2021-11-29 07:37:44 -05:00
let already_terminated = self . has_terminated . swap ( true , Ordering ::SeqCst ) ;
2021-05-11 15:09:09 -04:00
if ! already_terminated {
// Stop javascript execution
self . isolate_handle . terminate_execution ( ) ;
}
// Wake parent by closing the channel
self . sender . close_channel ( ) ;
}
2020-11-26 09:17:45 -05:00
}
2021-06-22 10:30:16 -04:00
pub struct SendableWebWorkerHandle {
port : MessagePort ,
receiver : mpsc ::Receiver < WorkerControlEvent > ,
2021-11-29 07:37:44 -05:00
termination_signal : Arc < AtomicBool > ,
has_terminated : Arc < AtomicBool > ,
terminate_waker : Arc < AtomicWaker > ,
2020-11-26 09:17:45 -05:00
isolate_handle : v8 ::IsolateHandle ,
}
2021-06-22 10:30:16 -04:00
impl From < SendableWebWorkerHandle > for WebWorkerHandle {
fn from ( handle : SendableWebWorkerHandle ) -> Self {
WebWorkerHandle {
receiver : Rc ::new ( RefCell ::new ( handle . receiver ) ) ,
port : Rc ::new ( handle . port ) ,
2021-11-29 07:37:44 -05:00
termination_signal : handle . termination_signal ,
has_terminated : handle . has_terminated ,
terminate_waker : handle . terminate_waker ,
2021-06-22 10:30:16 -04:00
isolate_handle : handle . isolate_handle ,
2021-04-19 10:57:02 -04:00
}
2020-11-26 09:17:45 -05:00
}
2021-06-22 10:30:16 -04:00
}
/// This is the handle to the web worker that the parent thread uses to
/// communicate with the worker. It is created from a `SendableWebWorkerHandle`
/// which is sent to the parent thread from the worker thread where it is
2021-08-20 16:14:48 -04:00
/// created. The reason for this separation is that the handle first needs to be
2021-06-22 10:30:16 -04:00
/// `Send` when transferring between threads, and then must be `Clone` when it
/// has arrived on the parent thread. It can not be both at once without large
/// amounts of Arc<Mutex> and other fun stuff.
#[ derive(Clone) ]
pub struct WebWorkerHandle {
pub port : Rc < MessagePort > ,
receiver : Rc < RefCell < mpsc ::Receiver < WorkerControlEvent > > > ,
2021-11-29 07:37:44 -05:00
termination_signal : Arc < AtomicBool > ,
has_terminated : Arc < AtomicBool > ,
terminate_waker : Arc < AtomicWaker > ,
2021-06-22 10:30:16 -04:00
isolate_handle : v8 ::IsolateHandle ,
}
2020-11-26 09:17:45 -05:00
2021-06-22 10:30:16 -04:00
impl WebWorkerHandle {
2021-05-11 15:09:09 -04:00
/// Get the WorkerEvent with lock
2020-11-26 09:17:45 -05:00
/// Return error if more than one listener tries to get event
2023-09-11 19:12:33 -04:00
#[ allow(clippy::await_holding_refcell_ref) ] // TODO(ry) remove!
2021-06-22 10:30:16 -04:00
pub async fn get_control_event (
& self ,
) -> Result < Option < WorkerControlEvent > , AnyError > {
let mut receiver = self . receiver . borrow_mut ( ) ;
2020-11-26 09:17:45 -05:00
Ok ( receiver . next ( ) . await )
}
2021-05-11 15:09:09 -04:00
/// Terminate the worker
2021-11-29 07:37:44 -05:00
/// This function will set the termination signal, close the message channel,
/// and schedule to terminate the isolate after two seconds.
2021-06-22 10:30:16 -04:00
pub fn terminate ( self ) {
2023-01-14 23:18:58 -05:00
use std ::thread ::sleep ;
use std ::thread ::spawn ;
2021-11-29 07:37:44 -05:00
use std ::time ::Duration ;
2020-11-26 09:17:45 -05:00
2021-11-29 07:37:44 -05:00
let schedule_termination =
! self . termination_signal . swap ( true , Ordering ::SeqCst ) ;
2021-05-11 15:09:09 -04:00
2021-06-22 10:30:16 -04:00
self . port . disentangle ( ) ;
2021-11-29 07:37:44 -05:00
if schedule_termination & & ! self . has_terminated . load ( Ordering ::SeqCst ) {
// Wake up the worker's event loop so it can terminate.
self . terminate_waker . wake ( ) ;
let has_terminated = self . has_terminated . clone ( ) ;
// Schedule to terminate the isolate's execution.
spawn ( move | | {
sleep ( Duration ::from_secs ( 2 ) ) ;
// A worker's isolate can only be terminated once, so we need a guard
// here.
let already_terminated = has_terminated . swap ( true , Ordering ::SeqCst ) ;
if ! already_terminated {
// Stop javascript execution
self . isolate_handle . terminate_execution ( ) ;
}
} ) ;
}
2020-11-26 09:17:45 -05:00
}
}
2021-05-11 15:09:09 -04:00
fn create_handles (
2020-11-26 09:17:45 -05:00
isolate_handle : v8 ::IsolateHandle ,
2022-04-13 05:50:57 -04:00
name : String ,
2021-08-16 08:29:54 -04:00
worker_type : WebWorkerType ,
2021-06-22 10:30:16 -04:00
) -> ( WebWorkerInternalHandle , SendableWebWorkerHandle ) {
let ( parent_port , worker_port ) = create_entangled_message_port ( ) ;
let ( ctrl_tx , ctrl_rx ) = mpsc ::channel ::< WorkerControlEvent > ( 1 ) ;
2021-11-29 07:37:44 -05:00
let termination_signal = Arc ::new ( AtomicBool ::new ( false ) ) ;
let has_terminated = Arc ::new ( AtomicBool ::new ( false ) ) ;
let terminate_waker = Arc ::new ( AtomicWaker ::new ( ) ) ;
2021-05-11 15:09:09 -04:00
let internal_handle = WebWorkerInternalHandle {
2022-04-13 05:50:57 -04:00
name ,
2021-06-22 10:30:16 -04:00
port : Rc ::new ( parent_port ) ,
2021-11-29 07:37:44 -05:00
termination_signal : termination_signal . clone ( ) ,
has_terminated : has_terminated . clone ( ) ,
terminate_waker : terminate_waker . clone ( ) ,
2021-05-11 15:09:09 -04:00
isolate_handle : isolate_handle . clone ( ) ,
2021-06-22 10:30:16 -04:00
cancel : CancelHandle ::new_rc ( ) ,
2022-04-13 05:50:57 -04:00
sender : ctrl_tx ,
2021-08-16 08:29:54 -04:00
worker_type ,
2020-11-26 09:17:45 -05:00
} ;
2021-06-22 10:30:16 -04:00
let external_handle = SendableWebWorkerHandle {
receiver : ctrl_rx ,
port : worker_port ,
2021-11-29 07:37:44 -05:00
termination_signal ,
has_terminated ,
terminate_waker ,
2020-11-26 09:17:45 -05:00
isolate_handle ,
} ;
2021-05-11 15:09:09 -04:00
( internal_handle , external_handle )
2020-11-26 09:17:45 -05:00
}
/// This struct is an implementation of `Worker` Web API
///
/// Each `WebWorker` is either a child of `MainWorker` or other
/// `WebWorker`.
pub struct WebWorker {
2021-05-11 15:09:09 -04:00
id : WorkerId ,
2020-12-13 13:45:53 -05:00
pub js_runtime : JsRuntime ,
pub name : String ,
2021-05-11 15:09:09 -04:00
internal_handle : WebWorkerInternalHandle ,
2021-08-16 08:29:54 -04:00
pub worker_type : WebWorkerType ,
2021-01-07 13:06:08 -05:00
pub main_module : ModuleSpecifier ,
2022-02-11 07:41:56 -05:00
poll_for_messages_fn : Option < v8 ::Global < v8 ::Value > > ,
2023-02-21 19:55:31 -05:00
bootstrap_fn_global : Option < v8 ::Global < v8 ::Function > > ,
2020-12-11 12:49:26 -05:00
}
pub struct WebWorkerOptions {
2021-10-05 16:41:14 -04:00
pub bootstrap : BootstrapOptions ,
2021-10-08 11:03:49 -04:00
pub extensions : Vec < Extension > ,
2022-11-21 08:36:26 -05:00
pub startup_snapshot : Option < Snapshot > ,
2021-08-10 07:19:45 -04:00
pub unsafely_ignore_certificate_errors : Option < Vec < String > > ,
2023-05-01 16:42:05 -04:00
pub root_cert_store_provider : Option < Arc < dyn RootCertStoreProvider > > ,
2020-12-11 12:49:26 -05:00
pub seed : Option < u64 > ,
2023-05-04 14:28:42 -04:00
pub fs : Arc < dyn FileSystem > ,
2020-12-11 12:49:26 -05:00
pub module_loader : Rc < dyn ModuleLoader > ,
2023-04-24 19:44:35 -04:00
pub npm_resolver : Option < Arc < dyn deno_node ::NpmResolver > > ,
2020-12-11 12:49:26 -05:00
pub create_web_worker_cb : Arc < ops ::worker_host ::CreateWebWorkerCb > ,
2022-04-26 19:06:10 -04:00
pub format_js_error_fn : Option < Arc < FormatJsErrorFn > > ,
2022-04-15 10:08:09 -04:00
pub source_map_getter : Option < Box < dyn SourceMapGetter > > ,
2021-08-16 08:29:54 -04:00
pub worker_type : WebWorkerType ,
2020-12-11 12:49:26 -05:00
pub maybe_inspector_server : Option < Arc < InspectorServer > > ,
2020-12-13 13:45:53 -05:00
pub get_error_class_fn : Option < GetErrorClassFn > ,
2023-07-01 18:52:30 -04:00
pub blob_store : Arc < BlobStore > ,
2021-05-22 12:08:24 -04:00
pub broadcast_channel : InMemoryBroadcastChannel ,
2021-07-06 13:42:52 -04:00
pub shared_array_buffer_store : Option < SharedArrayBufferStore > ,
2021-09-29 04:47:24 -04:00
pub compiled_wasm_module_store : Option < CompiledWasmModuleStore > ,
2022-09-28 08:11:12 -04:00
pub cache_storage_dir : Option < std ::path ::PathBuf > ,
2022-04-26 19:00:04 -04:00
pub stdio : Stdio ,
2023-10-12 11:55:50 -04:00
pub feature_checker : Arc < FeatureChecker > ,
2020-11-26 09:17:45 -05:00
}
impl WebWorker {
2021-10-05 16:41:14 -04:00
pub fn bootstrap_from_options (
name : String ,
2023-01-07 11:25:34 -05:00
permissions : PermissionsContainer ,
2021-10-05 16:41:14 -04:00
main_module : ModuleSpecifier ,
worker_id : WorkerId ,
options : WebWorkerOptions ,
) -> ( Self , SendableWebWorkerHandle ) {
let bootstrap_options = options . bootstrap . clone ( ) ;
let ( mut worker , handle ) =
Self ::from_options ( name , permissions , main_module , worker_id , options ) ;
worker . bootstrap ( & bootstrap_options ) ;
( worker , handle )
}
2020-12-11 12:49:26 -05:00
pub fn from_options (
2020-11-26 09:17:45 -05:00
name : String ,
2023-01-07 11:25:34 -05:00
permissions : PermissionsContainer ,
2020-11-26 09:17:45 -05:00
main_module : ModuleSpecifier ,
2021-05-11 15:09:09 -04:00
worker_id : WorkerId ,
2021-10-08 11:03:49 -04:00
mut options : WebWorkerOptions ,
2021-06-22 10:30:16 -04:00
) -> ( Self , SendableWebWorkerHandle ) {
2023-03-17 14:22:15 -04:00
deno_core ::extension! ( deno_permissions_web_worker ,
2023-03-17 18:15:27 -04:00
options = {
2023-03-17 14:22:15 -04:00
permissions : PermissionsContainer ,
enable_testing_features : bool ,
} ,
2023-03-17 18:15:27 -04:00
state = | state , options | {
state . put ::< PermissionsContainer > ( options . permissions ) ;
state . put ( ops ::TestingFeaturesEnabled ( options . enable_testing_features ) ) ;
2023-03-17 14:22:15 -04:00
} ,
) ;
2021-05-02 19:22:57 -04:00
// Permissions: many ops depend on this
2021-10-05 16:41:14 -04:00
let enable_testing_features = options . bootstrap . enable_testing_features ;
2023-03-09 15:09:45 -05:00
let create_cache = options . cache_storage_dir . map ( | storage_dir | {
let create_cache_fn = move | | SqliteBackedCache ::new ( storage_dir . clone ( ) ) ;
CreateCache ( Arc ::new ( create_cache_fn ) )
} ) ;
2023-03-16 13:36:53 -04:00
// NOTE(bartlomieju): ordering is important here, keep it in sync with
2024-01-10 10:30:50 -05:00
// `runtime/worker.rs` and `runtime/snapshot.rs`!
2023-08-05 19:47:15 -04:00
let mut extensions = vec! [
2023-03-09 15:09:45 -05:00
// Web APIs
2023-08-05 19:47:15 -04:00
deno_webidl ::deno_webidl ::init_ops_and_esm ( ) ,
deno_console ::deno_console ::init_ops_and_esm ( ) ,
deno_url ::deno_url ::init_ops_and_esm ( ) ,
deno_web ::deno_web ::init_ops_and_esm ::< PermissionsContainer > (
2023-03-09 15:09:45 -05:00
options . blob_store . clone ( ) ,
Some ( main_module . clone ( ) ) ,
) ,
2023-12-08 19:19:16 -05:00
deno_webgpu ::deno_webgpu ::init_ops_and_esm ( ) ,
2023-08-05 19:47:15 -04:00
deno_fetch ::deno_fetch ::init_ops_and_esm ::< PermissionsContainer > (
2023-03-17 14:22:15 -04:00
deno_fetch ::Options {
user_agent : options . bootstrap . user_agent . clone ( ) ,
2023-05-01 16:42:05 -04:00
root_cert_store_provider : options . root_cert_store_provider . clone ( ) ,
2023-03-17 14:22:15 -04:00
unsafely_ignore_certificate_errors : options
. unsafely_ignore_certificate_errors
. clone ( ) ,
file_fetch_handler : Rc ::new ( deno_fetch ::FsFetchHandler ) ,
.. Default ::default ( )
} ,
) ,
2023-08-05 19:47:15 -04:00
deno_cache ::deno_cache ::init_ops_and_esm ::< SqliteBackedCache > (
create_cache ,
) ,
deno_websocket ::deno_websocket ::init_ops_and_esm ::< PermissionsContainer > (
2023-03-09 15:09:45 -05:00
options . bootstrap . user_agent . clone ( ) ,
2023-05-01 16:42:05 -04:00
options . root_cert_store_provider . clone ( ) ,
2023-03-09 15:09:45 -05:00
options . unsafely_ignore_certificate_errors . clone ( ) ,
) ,
2023-08-05 19:47:15 -04:00
deno_webstorage ::deno_webstorage ::init_ops_and_esm ( None ) . disable ( ) ,
deno_crypto ::deno_crypto ::init_ops_and_esm ( options . seed ) ,
deno_broadcast_channel ::deno_broadcast_channel ::init_ops_and_esm (
2023-03-09 15:09:45 -05:00
options . broadcast_channel . clone ( ) ,
) ,
2023-10-04 15:42:17 -04:00
deno_ffi ::deno_ffi ::init_ops_and_esm ::< PermissionsContainer > ( ) ,
2023-08-05 19:47:15 -04:00
deno_net ::deno_net ::init_ops_and_esm ::< PermissionsContainer > (
2023-05-01 16:42:05 -04:00
options . root_cert_store_provider . clone ( ) ,
2023-03-16 13:36:53 -04:00
options . unsafely_ignore_certificate_errors . clone ( ) ,
) ,
2023-08-05 19:47:15 -04:00
deno_tls ::deno_tls ::init_ops_and_esm ( ) ,
deno_kv ::deno_kv ::init_ops_and_esm (
2023-10-31 07:13:57 -04:00
MultiBackendDbHandler ::remote_or_sqlite ::< PermissionsContainer > (
None ,
options . seed ,
deno_kv ::remote ::HttpOptions {
user_agent : options . bootstrap . user_agent . clone ( ) ,
root_cert_store_provider : options . root_cert_store_provider . clone ( ) ,
unsafely_ignore_certificate_errors : options
. unsafely_ignore_certificate_errors
. clone ( ) ,
client_cert_chain_and_key : None ,
proxy : None ,
} ,
) ,
2023-03-22 00:13:24 -04:00
) ,
2023-11-01 14:57:55 -04:00
deno_cron ::deno_cron ::init_ops_and_esm ( LocalCronHandler ::new ( ) ) ,
2023-08-05 19:47:15 -04:00
deno_napi ::deno_napi ::init_ops_and_esm ::< PermissionsContainer > ( ) ,
deno_http ::deno_http ::init_ops_and_esm ::< DefaultHttpPropertyExtractor > ( ) ,
deno_io ::deno_io ::init_ops_and_esm ( Some ( options . stdio ) ) ,
deno_fs ::deno_fs ::init_ops_and_esm ::< PermissionsContainer > (
2023-05-05 12:44:24 -04:00
options . fs . clone ( ) ,
) ,
2023-08-05 19:47:15 -04:00
deno_node ::deno_node ::init_ops_and_esm ::< PermissionsContainer > (
2023-03-17 14:22:15 -04:00
options . npm_resolver ,
2023-05-05 12:44:24 -04:00
options . fs ,
2023-03-17 14:22:15 -04:00
) ,
2023-03-09 15:09:45 -05:00
// Runtime ops that are always initialized for WebWorkers
2023-08-05 19:47:15 -04:00
ops ::runtime ::deno_runtime ::init_ops_and_esm ( main_module . clone ( ) ) ,
ops ::worker_host ::deno_worker_host ::init_ops_and_esm (
2023-03-09 15:09:45 -05:00
options . create_web_worker_cb . clone ( ) ,
options . format_js_error_fn . clone ( ) ,
) ,
2023-08-05 19:47:15 -04:00
ops ::fs_events ::deno_fs_events ::init_ops_and_esm ( ) ,
ops ::os ::deno_os_worker ::init_ops_and_esm ( ) ,
ops ::permissions ::deno_permissions ::init_ops_and_esm ( ) ,
ops ::process ::deno_process ::init_ops_and_esm ( ) ,
ops ::signal ::deno_signal ::init_ops_and_esm ( ) ,
ops ::tty ::deno_tty ::init_ops_and_esm ( ) ,
ops ::http ::deno_http_runtime ::init_ops_and_esm ( ) ,
2023-11-15 07:25:55 -05:00
ops ::bootstrap ::deno_bootstrap ::init_ops_and_esm ( None ) ,
2023-08-05 19:47:15 -04:00
deno_permissions_web_worker ::init_ops_and_esm (
2023-03-17 14:22:15 -04:00
permissions ,
enable_testing_features ,
) ,
2023-08-05 19:47:15 -04:00
runtime ::init_ops_and_esm ( ) ,
2023-11-11 12:01:48 -05:00
ops ::web_worker ::deno_web_worker ::init_ops_and_esm ( ) ,
2023-03-09 15:09:45 -05:00
] ;
2021-04-28 12:41:50 -04:00
2023-08-05 19:47:15 -04:00
for extension in & mut extensions {
#[ cfg(not(feature = " __runtime_js_sources " )) ]
{
extension . js_files = std ::borrow ::Cow ::Borrowed ( & [ ] ) ;
extension . esm_files = std ::borrow ::Cow ::Borrowed ( & [ ] ) ;
extension . esm_entry_point = None ;
}
#[ cfg(feature = " __runtime_js_sources " ) ]
{
2023-08-28 17:30:46 -04:00
use crate ::shared ::maybe_transpile_source ;
2023-08-05 19:47:15 -04:00
for source in extension . esm_files . to_mut ( ) {
maybe_transpile_source ( source ) . unwrap ( ) ;
}
for source in extension . js_files . to_mut ( ) {
maybe_transpile_source ( source ) . unwrap ( ) ;
}
}
}
2021-10-08 11:03:49 -04:00
extensions . extend ( std ::mem ::take ( & mut options . extensions ) ) ;
2021-05-02 19:22:57 -04:00
2024-01-10 10:30:50 -05:00
#[ cfg(all(
feature = " include_js_files_for_snapshotting " ,
not ( feature = " __runtime_js_sources " )
) ) ]
options
. startup_snapshot
. as_ref ( )
. expect ( " Sources are not embedded and a user snapshot was not provided. " ) ;
#[ cfg(not(feature = " dont_use_runtime_snapshot " )) ]
options . startup_snapshot . as_ref ( ) . expect ( " A user snapshot was not provided, if you want to create a runtime without a snapshot use 'dont_use_runtime_snapshot' Cargo feature. " ) ;
2023-02-20 15:45:34 -05:00
2023-11-05 16:27:36 -05:00
// Hook up the summary metrics if the user or subcommand requested them
let ( op_summary_metrics , op_metrics_factory_fn ) =
if options . bootstrap . enable_op_summary_metrics {
let op_summary_metrics = Rc ::new ( OpMetricsSummaryTracker ::default ( ) ) ;
(
Some ( op_summary_metrics . clone ( ) ) ,
Some ( op_summary_metrics . op_metrics_factory_fn ( | _ | true ) ) ,
)
} else {
( None , None )
} ;
2020-11-26 09:17:45 -05:00
let mut js_runtime = JsRuntime ::new ( RuntimeOptions {
2020-12-11 12:49:26 -05:00
module_loader : Some ( options . module_loader . clone ( ) ) ,
2024-01-10 10:30:50 -05:00
startup_snapshot : options . startup_snapshot ,
2022-04-15 10:08:09 -04:00
source_map_getter : options . source_map_getter ,
2020-12-13 13:45:53 -05:00
get_error_class_fn : options . get_error_class_fn ,
2021-07-06 13:42:52 -04:00
shared_array_buffer_store : options . shared_array_buffer_store . clone ( ) ,
2021-09-29 04:47:24 -04:00
compiled_wasm_module_store : options . compiled_wasm_module_store . clone ( ) ,
2021-04-28 12:41:50 -04:00
extensions ,
2022-10-26 07:37:50 -04:00
inspector : options . maybe_inspector_server . is_some ( ) ,
2023-10-12 11:55:50 -04:00
feature_checker : Some ( options . feature_checker . clone ( ) ) ,
2023-11-05 16:27:36 -05:00
op_metrics_factory_fn ,
2023-12-28 14:37:10 -05:00
import_meta_resolve_callback : Some ( Box ::new (
import_meta_resolve_callback ,
) ) ,
2020-11-26 09:17:45 -05:00
.. Default ::default ( )
} ) ;
2023-11-05 16:27:36 -05:00
if let Some ( op_summary_metrics ) = op_summary_metrics {
js_runtime . op_state ( ) . borrow_mut ( ) . put ( op_summary_metrics ) ;
}
2021-06-21 13:37:51 -04:00
if let Some ( server ) = options . maybe_inspector_server . clone ( ) {
2021-12-17 12:43:25 -05:00
server . register_inspector (
main_module . to_string ( ) ,
& mut js_runtime ,
false ,
) ;
2022-11-28 15:59:36 -05:00
// Put inspector handle into the op state so we can put a breakpoint when
// executing a CJS entrypoint.
let op_state = js_runtime . op_state ( ) ;
let inspector = js_runtime . inspector ( ) ;
op_state . borrow_mut ( ) . put ( inspector ) ;
2021-05-26 15:07:12 -04:00
}
2020-11-26 09:17:45 -05:00
2021-05-11 15:09:09 -04:00
let ( internal_handle , external_handle ) = {
let handle = js_runtime . v8_isolate ( ) . thread_safe_handle ( ) ;
2021-08-16 08:29:54 -04:00
let ( internal_handle , external_handle ) =
2022-04-13 05:50:57 -04:00
create_handles ( handle , name . clone ( ) , options . worker_type ) ;
2021-05-11 15:09:09 -04:00
let op_state = js_runtime . op_state ( ) ;
let mut op_state = op_state . borrow_mut ( ) ;
op_state . put ( internal_handle . clone ( ) ) ;
( internal_handle , external_handle )
} ;
2020-11-26 09:17:45 -05:00
2023-02-21 19:55:31 -05:00
let bootstrap_fn_global = {
2023-07-23 09:42:41 -04:00
let context = js_runtime . main_context ( ) ;
2023-02-21 19:55:31 -05:00
let scope = & mut js_runtime . handle_scope ( ) ;
let context_local = v8 ::Local ::new ( scope , context ) ;
let global_obj = context_local . global ( scope ) ;
2023-03-06 11:37:46 -05:00
let bootstrap_str =
v8 ::String ::new_external_onebyte_static ( scope , b " bootstrap " ) . unwrap ( ) ;
2023-02-21 19:55:31 -05:00
let bootstrap_ns : v8 ::Local < v8 ::Object > = global_obj
. get ( scope , bootstrap_str . into ( ) )
. unwrap ( )
. try_into ( )
. unwrap ( ) ;
2023-03-06 11:37:46 -05:00
let main_runtime_str =
v8 ::String ::new_external_onebyte_static ( scope , b " workerRuntime " )
. unwrap ( ) ;
2023-02-21 19:55:31 -05:00
let bootstrap_fn =
bootstrap_ns . get ( scope , main_runtime_str . into ( ) ) . unwrap ( ) ;
let bootstrap_fn =
v8 ::Local ::< v8 ::Function > ::try_from ( bootstrap_fn ) . unwrap ( ) ;
v8 ::Global ::new ( scope , bootstrap_fn )
} ;
2021-06-22 10:30:16 -04:00
(
Self {
id : worker_id ,
js_runtime ,
name ,
internal_handle ,
2021-08-16 08:29:54 -04:00
worker_type : options . worker_type ,
2021-06-22 10:30:16 -04:00
main_module ,
2022-02-11 07:41:56 -05:00
poll_for_messages_fn : None ,
2023-02-21 19:55:31 -05:00
bootstrap_fn_global : Some ( bootstrap_fn_global ) ,
2021-06-22 10:30:16 -04:00
} ,
2021-05-11 15:09:09 -04:00
external_handle ,
2021-06-22 10:30:16 -04:00
)
2020-12-11 12:49:26 -05:00
}
2021-10-05 16:41:14 -04:00
pub fn bootstrap ( & mut self , options : & BootstrapOptions ) {
2023-11-12 23:52:59 -05:00
self . js_runtime . op_state ( ) . borrow_mut ( ) . put ( options . clone ( ) ) ;
2020-12-06 22:30:40 -05:00
// Instead of using name for log we use `worker-${id}` because
// WebWorkers can have empty string as name.
2023-02-21 19:55:31 -05:00
{
let scope = & mut self . js_runtime . handle_scope ( ) ;
2023-03-28 04:27:17 -04:00
let args = options . as_v8 ( scope ) ;
2023-02-21 19:55:31 -05:00
let bootstrap_fn = self . bootstrap_fn_global . take ( ) . unwrap ( ) ;
let bootstrap_fn = v8 ::Local ::new ( scope , bootstrap_fn ) ;
let undefined = v8 ::undefined ( scope ) ;
let name_str : v8 ::Local < v8 ::Value > =
v8 ::String ::new ( scope , & self . name ) . unwrap ( ) . into ( ) ;
let id_str : v8 ::Local < v8 ::Value > =
v8 ::String ::new ( scope , & format! ( " {} " , self . id ) )
. unwrap ( )
. into ( ) ;
bootstrap_fn
2023-08-15 15:36:36 -04:00
. call ( scope , undefined . into ( ) , & [ args , name_str , id_str ] )
2023-02-21 19:55:31 -05:00
. unwrap ( ) ;
}
// TODO(bartlomieju): this could be done using V8 API, without calling `execute_script`.
2022-02-11 07:41:56 -05:00
// Save a reference to function that will start polling for messages
// from a worker host; it will be called after the user code is loaded.
2023-04-04 08:46:31 -04:00
let script = ascii_str! (
r #"
2022-02-11 07:41:56 -05:00
const pollForMessages = globalThis . pollForMessages ;
delete globalThis . pollForMessages ;
pollForMessages
2023-04-04 08:46:31 -04:00
" #
) ;
2022-02-11 07:41:56 -05:00
let poll_for_messages_fn = self
. js_runtime
2023-03-21 18:33:12 -04:00
. execute_script ( located_script_name! ( ) , script )
2022-02-11 07:41:56 -05:00
. expect ( " Failed to execute worker bootstrap script " ) ;
self . poll_for_messages_fn = Some ( poll_for_messages_fn ) ;
2020-11-26 09:17:45 -05:00
}
2021-06-21 19:45:41 -04:00
/// See [JsRuntime::execute_script](deno_core::JsRuntime::execute_script)
2023-04-04 08:46:31 -04:00
pub fn execute_script (
2021-06-21 19:45:41 -04:00
& mut self ,
2023-03-21 18:33:12 -04:00
name : & 'static str ,
2024-01-09 23:18:40 -05:00
source_code : ModuleCodeString ,
2021-06-21 19:45:41 -04:00
) -> Result < ( ) , AnyError > {
2021-07-08 12:56:53 -04:00
self . js_runtime . execute_script ( name , source_code ) ? ;
Ok ( ( ) )
2020-11-26 09:17:45 -05:00
}
2022-08-10 18:10:51 -04:00
/// Loads and instantiates specified JavaScript module as "main" module.
pub async fn preload_main_module (
2021-05-11 15:09:09 -04:00
& mut self ,
module_specifier : & ModuleSpecifier ,
) -> Result < ModuleId , AnyError > {
2022-08-10 18:10:51 -04:00
self
. js_runtime
. load_main_module ( module_specifier , None )
. await
}
/// Loads and instantiates specified JavaScript module as "side" module.
pub async fn preload_side_module (
& mut self ,
module_specifier : & ModuleSpecifier ,
) -> Result < ModuleId , AnyError > {
self
. js_runtime
. load_side_module ( module_specifier , None )
. await
2021-05-11 15:09:09 -04:00
}
2020-11-26 09:17:45 -05:00
/// Loads, instantiates and executes specified JavaScript module.
2022-02-11 07:41:56 -05:00
///
/// This method assumes that worker can't be terminated when executing
/// side module code.
pub async fn execute_side_module (
2020-11-26 09:17:45 -05:00
& mut self ,
module_specifier : & ModuleSpecifier ,
) -> Result < ( ) , AnyError > {
2022-08-10 18:10:51 -04:00
let id = self . preload_side_module ( module_specifier ) . await ? ;
2022-02-11 07:41:56 -05:00
let mut receiver = self . js_runtime . mod_evaluate ( id ) ;
tokio ::select! {
2022-05-10 05:26:57 -04:00
biased ;
2022-02-11 07:41:56 -05:00
maybe_result = & mut receiver = > {
debug! ( " received module evaluate {:#?} " , maybe_result ) ;
2023-11-27 18:01:27 -05:00
maybe_result
2022-02-11 07:41:56 -05:00
}
2023-12-13 10:07:26 -05:00
event_loop_result = self . js_runtime . run_event_loop ( PollEventLoopOptions ::default ( ) ) = > {
2022-02-11 07:41:56 -05:00
event_loop_result ? ;
2023-11-27 18:01:27 -05:00
receiver . await
2022-02-11 07:41:56 -05:00
}
}
}
/// Loads, instantiates and executes specified JavaScript module.
///
/// This module will have "import.meta.main" equal to true.
pub async fn execute_main_module (
& mut self ,
id : ModuleId ,
) -> Result < ( ) , AnyError > {
2021-03-04 07:19:47 -05:00
let mut receiver = self . js_runtime . mod_evaluate ( id ) ;
2023-12-13 10:07:26 -05:00
let poll_options = PollEventLoopOptions ::default ( ) ;
2023-11-26 18:09:04 -05:00
2021-03-04 07:19:47 -05:00
tokio ::select! {
2022-05-10 05:26:57 -04:00
biased ;
2021-07-30 07:36:43 -04:00
maybe_result = & mut receiver = > {
2021-03-04 07:19:47 -05:00
debug! ( " received worker module evaluate {:#?} " , maybe_result ) ;
2023-11-27 18:01:27 -05:00
maybe_result
2021-03-04 07:19:47 -05:00
}
2023-11-26 18:09:04 -05:00
event_loop_result = self . run_event_loop ( poll_options ) = > {
2021-05-11 15:09:09 -04:00
if self . internal_handle . is_terminated ( ) {
return Ok ( ( ) ) ;
2021-03-04 07:19:47 -05:00
}
event_loop_result ? ;
2023-11-27 18:01:27 -05:00
receiver . await
2021-03-04 07:19:47 -05:00
}
}
2020-11-26 09:17:45 -05:00
}
2021-09-24 18:35:35 -04:00
fn poll_event_loop (
2020-11-26 09:17:45 -05:00
& mut self ,
cx : & mut Context ,
2023-11-26 18:09:04 -05:00
poll_options : PollEventLoopOptions ,
2020-11-26 09:17:45 -05:00
) -> Poll < Result < ( ) , AnyError > > {
2021-05-11 15:09:09 -04:00
// If awakened because we are terminating, just return Ok
2021-11-29 07:37:44 -05:00
if self . internal_handle . terminate_if_needed ( ) {
2020-11-26 09:17:45 -05:00
return Poll ::Ready ( Ok ( ( ) ) ) ;
}
2021-11-29 07:37:44 -05:00
self . internal_handle . terminate_waker . register ( cx . waker ( ) ) ;
2023-12-13 10:07:26 -05:00
match self . js_runtime . poll_event_loop ( cx , poll_options ) {
2021-05-11 15:09:09 -04:00
Poll ::Ready ( r ) = > {
// If js ended because we are terminating, just return Ok
2021-11-29 07:37:44 -05:00
if self . internal_handle . terminate_if_needed ( ) {
2020-12-06 22:30:40 -05:00
return Poll ::Ready ( Ok ( ( ) ) ) ;
2020-11-26 09:17:45 -05:00
}
2020-12-06 22:30:40 -05:00
if let Err ( e ) = r {
2021-10-01 05:30:55 -04:00
return Poll ::Ready ( Err ( e ) ) ;
2020-11-26 09:17:45 -05:00
}
2020-12-06 22:30:40 -05:00
2023-11-22 12:02:13 -05:00
// TODO(mmastrac): we don't want to test this w/classic workers because
// WPT triggers a failure here. This is only exposed via --enable-testing-features-do-not-use.
if self . worker_type = = WebWorkerType ::Module {
panic! (
" coding error: either js is polling or the worker is terminated "
) ;
} else {
eprintln! ( " classic worker terminated unexpectedly " ) ;
Poll ::Ready ( Ok ( ( ) ) )
}
2020-11-26 09:17:45 -05:00
}
2021-05-11 15:09:09 -04:00
Poll ::Pending = > Poll ::Pending ,
2020-11-26 09:17:45 -05:00
}
}
2021-05-26 15:07:12 -04:00
pub async fn run_event_loop (
& mut self ,
2023-11-26 18:09:04 -05:00
poll_options : PollEventLoopOptions ,
2021-05-26 15:07:12 -04:00
) -> Result < ( ) , AnyError > {
2023-11-26 18:09:04 -05:00
poll_fn ( | cx | self . poll_event_loop ( cx , poll_options ) ) . await
2020-11-26 09:17:45 -05:00
}
2022-02-11 07:41:56 -05:00
// Starts polling for messages from worker host from JavaScript.
fn start_polling_for_messages ( & mut self ) {
let poll_for_messages_fn = self . poll_for_messages_fn . take ( ) . unwrap ( ) ;
let scope = & mut self . js_runtime . handle_scope ( ) ;
let poll_for_messages =
v8 ::Local ::< v8 ::Value > ::new ( scope , poll_for_messages_fn ) ;
let fn_ = v8 ::Local ::< v8 ::Function > ::try_from ( poll_for_messages ) . unwrap ( ) ;
let undefined = v8 ::undefined ( scope ) ;
2022-04-19 04:59:51 -04:00
// This call may return `None` if worker is terminated.
fn_ . call ( scope , undefined . into ( ) , & [ ] ) ;
2022-02-11 07:41:56 -05:00
}
2020-11-26 09:17:45 -05:00
}
2022-04-26 19:06:10 -04:00
fn print_worker_error (
error : & AnyError ,
name : & str ,
format_js_error_fn : Option < & FormatJsErrorFn > ,
) {
let error_str = match format_js_error_fn {
Some ( format_js_error_fn ) = > match error . downcast_ref ::< JsError > ( ) {
Some ( js_error ) = > format_js_error_fn ( js_error ) ,
None = > error . to_string ( ) ,
} ,
None = > error . to_string ( ) ,
} ;
2020-12-06 22:30:40 -05:00
eprintln! (
" {}: Uncaught (in worker \" {} \" ) {} " ,
colors ::red_bold ( " error " ) ,
name ,
error_str . trim_start_matches ( " Uncaught " ) ,
) ;
}
/// This function should be called from a thread dedicated to this worker.
// TODO(bartlomieju): check if order of actions is aligned to Worker spec
pub fn run_web_worker (
2023-08-15 15:36:36 -04:00
mut worker : WebWorker ,
2020-12-06 22:30:40 -05:00
specifier : ModuleSpecifier ,
2023-03-21 18:33:12 -04:00
mut maybe_source_code : Option < String > ,
2022-04-26 19:06:10 -04:00
format_js_error_fn : Option < Arc < FormatJsErrorFn > > ,
2020-12-06 22:30:40 -05:00
) -> Result < ( ) , AnyError > {
let name = worker . name . to_string ( ) ;
// TODO(bartlomieju): run following block using "select!"
// with terminate
2021-08-18 09:19:22 -04:00
let fut = async move {
2022-02-11 07:41:56 -05:00
let internal_handle = worker . internal_handle . clone ( ) ;
2021-08-18 09:19:22 -04:00
// Execute provided source code immediately
2023-03-21 18:33:12 -04:00
let result = if let Some ( source_code ) = maybe_source_code . take ( ) {
2023-04-04 08:46:31 -04:00
let r = worker . execute_script ( located_script_name! ( ) , source_code . into ( ) ) ;
2022-02-11 07:41:56 -05:00
worker . start_polling_for_messages ( ) ;
r
2021-08-18 09:19:22 -04:00
} else {
// TODO(bartlomieju): add "type": "classic", ie. ability to load
// script instead of module
2022-08-10 18:10:51 -04:00
match worker . preload_main_module ( & specifier ) . await {
2022-02-11 07:41:56 -05:00
Ok ( id ) = > {
worker . start_polling_for_messages ( ) ;
worker . execute_main_module ( id ) . await
}
Err ( e ) = > Err ( e ) ,
}
2021-08-18 09:19:22 -04:00
} ;
2020-12-06 22:30:40 -05:00
2021-08-18 09:19:22 -04:00
// If sender is closed it means that worker has already been closed from
// within using "globalThis.close()"
if internal_handle . is_terminated ( ) {
return Ok ( ( ) ) ;
}
2020-12-06 22:30:40 -05:00
2021-10-01 05:30:55 -04:00
let result = if result . is_ok ( ) {
2023-11-26 18:09:04 -05:00
worker
. run_event_loop ( PollEventLoopOptions {
wait_for_inspector : true ,
.. Default ::default ( )
} )
. await
2021-10-01 05:30:55 -04:00
} else {
result
} ;
2021-08-18 09:19:22 -04:00
if let Err ( e ) = result {
2022-04-26 19:06:10 -04:00
print_worker_error ( & e , & name , format_js_error_fn . as_deref ( ) ) ;
2021-08-18 09:19:22 -04:00
internal_handle
. post_event ( WorkerControlEvent ::TerminalError ( e ) )
. expect ( " Failed to post message to host " ) ;
2020-12-06 22:30:40 -05:00
2021-08-18 09:19:22 -04:00
// Failure to execute script is a terminal error, bye, bye.
return Ok ( ( ) ) ;
}
2020-12-06 22:30:40 -05:00
2021-08-18 09:19:22 -04:00
debug! ( " Worker thread shuts down {} " , & name ) ;
result
} ;
2023-05-14 17:40:01 -04:00
create_and_run_current_thread ( fut )
2020-12-06 22:30:40 -05:00
}