0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-07 23:06:50 -05:00

populate data on bootstrap

This commit is contained in:
Satya Rohith 2024-03-11 23:39:28 +05:30
parent c19a9d9794
commit 7d7ebef4e2
No known key found for this signature in database
GPG key ID: B2705CF40523EB05
6 changed files with 39 additions and 74 deletions

View file

@ -841,7 +841,7 @@ fn create_web_worker_callback(
stdio: stdio.clone(), stdio: stdio.clone(),
cache_storage_dir, cache_storage_dir,
feature_checker, feature_checker,
maybe_worker_data: args.maybe_worker_data, maybe_worker_metadata: args.maybe_worker_metadata,
}; };
WebWorker::bootstrap_from_options( WebWorker::bootstrap_from_options(

View file

@ -14,7 +14,7 @@ function initialize(
usesLocalNodeModulesDir, usesLocalNodeModulesDir,
argv0, argv0,
runningOnMainThread, runningOnMainThread,
maybeWorkerData, maybeWorkerMetadata,
) { ) {
if (initialized) { if (initialized) {
throw Error("Node runtime already initialized"); throw Error("Node runtime already initialized");
@ -39,7 +39,7 @@ function initialize(
// FIXME(bartlomieju): not nice to depend on `Deno` namespace here // FIXME(bartlomieju): not nice to depend on `Deno` namespace here
// but it's the only way to get `args` and `version` and this point. // but it's the only way to get `args` and `version` and this point.
internals.__bootstrapNodeProcess(argv0, Deno.args, Deno.version); internals.__bootstrapNodeProcess(argv0, Deno.args, Deno.version);
internals.__initWorkerThreads(runningOnMainThread, maybeWorkerData); internals.__initWorkerThreads(runningOnMainThread, maybeWorkerMetadata);
internals.__setupChildProcessIpcChannel(); internals.__setupChildProcessIpcChannel();
// `Deno[Deno.internal].requireImpl` will be unreachable after this line. // `Deno[Deno.internal].requireImpl` will be unreachable after this line.
delete internals.requireImpl; delete internals.requireImpl;

View file

@ -22,7 +22,7 @@ import {
import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as webidl from "ext:deno_webidl/00_webidl.js";
import { log } from "ext:runtime/06_util.js"; import { log } from "ext:runtime/06_util.js";
import { notImplemented } from "ext:deno_node/_utils.ts"; import { notImplemented } from "ext:deno_node/_utils.ts";
import { EventEmitter, once } from "node:events"; import { EventEmitter } from "node:events";
import { BroadcastChannel } from "ext:deno_broadcast_channel/01_broadcast_channel.js"; import { BroadcastChannel } from "ext:deno_broadcast_channel/01_broadcast_channel.js";
import { isAbsolute, resolve } from "node:path"; import { isAbsolute, resolve } from "node:path";
@ -42,7 +42,6 @@ const {
SafeRegExp, SafeRegExp,
SafeMap, SafeMap,
TypeError, TypeError,
PromisePrototypeThen,
} = primordials; } = primordials;
export interface WorkerOptions { export interface WorkerOptions {
@ -196,12 +195,13 @@ class NodeWorker extends EventEmitter {
name = "[worker eval]"; name = "[worker eval]";
} }
this.#name = name; this.#name = name;
this.threadId = ++threads;
const maybeWorkerData = options?.workerData; const serializedWorkerMetadata = serializeJsMessageData({
const serializedWorkerData = maybeWorkerData workerData: options?.workerData,
? core.serialize(maybeWorkerData) environmentData: environmentData,
: undefined; threadId: this.threadId,
}, options?.transferList ?? []);
const id = op_create_worker( const id = op_create_worker(
{ {
// deno-lint-ignore prefer-primordials // deno-lint-ignore prefer-primordials
@ -212,15 +212,11 @@ class NodeWorker extends EventEmitter {
name: this.#name, name: this.#name,
workerType: "module", workerType: "module",
}, },
serializedWorkerMetadata,
); );
this.#id = id; this.#id = id;
this.#pollControl(); this.#pollControl();
this.#pollMessages(); this.#pollMessages();
this.postMessage({
environmentData,
threadId: (this.threadId = ++threads),
}, options?.transferList || []);
// https://nodejs.org/api/worker_threads.html#event-online // https://nodejs.org/api/worker_threads.html#event-online
this.emit("online"); this.emit("online");
} }
@ -394,7 +390,7 @@ let parentPort: ParentPort = null as any;
internals.__initWorkerThreads = ( internals.__initWorkerThreads = (
runningOnMainThread: boolean, runningOnMainThread: boolean,
maybeWorkerData, maybeWorkerMetadata,
) => { ) => {
isMainThread = runningOnMainThread; isMainThread = runningOnMainThread;
@ -417,29 +413,13 @@ internals.__initWorkerThreads = (
>(); >();
parentPort = self as ParentPort; parentPort = self as ParentPort;
workerData = maybeWorkerData; const { 0: metadata, 1: _ } = maybeWorkerMetadata;
workerData = metadata.workerData;
environmentData = metadata.environmentData;
threadId = metadata.threadId;
defaultExport.workerData = workerData; defaultExport.workerData = workerData;
defaultExport.parentPort = parentPort; defaultExport.parentPort = parentPort;
defaultExport.threadId = threadId;
const initPromise = PromisePrototypeThen(
once(
parentPort,
"message",
),
(result) => {
// TODO(bartlomieju): just so we don't error out here. It's still racy,
// but should be addressed by https://github.com/denoland/deno/issues/22783
// shortly.
const data = result[0].data ?? {};
// TODO(kt3k): The below values are set asynchronously
// using the first message from the parent.
// This should be done synchronously.
threadId = data.threadId;
environmentData = data.environmentData;
defaultExport.threadId = threadId;
},
);
parentPort.off = parentPort.removeListener = function ( parentPort.off = parentPort.removeListener = function (
this: ParentPort, this: ParentPort,
@ -455,22 +435,18 @@ internals.__initWorkerThreads = (
name, name,
listener, listener,
) { ) {
PromisePrototypeThen(initPromise, () => { // deno-lint-ignore no-explicit-any
// deno-lint-ignore no-explicit-any const _listener = (ev: any) => listener(ev.data);
const _listener = (ev: any) => listener(ev.data); listeners.set(listener, _listener);
listeners.set(listener, _listener); this.addEventListener(name, _listener);
this.addEventListener(name, _listener);
});
return this; return this;
}; };
parentPort.once = function (this: ParentPort, name, listener) { parentPort.once = function (this: ParentPort, name, listener) {
PromisePrototypeThen(initPromise, () => { // deno-lint-ignore no-explicit-any
// deno-lint-ignore no-explicit-any const _listener = (ev: any) => listener(ev.data);
const _listener = (ev: any) => listener(ev.data); listeners.set(listener, _listener);
listeners.set(listener, _listener); this.addEventListener(name, _listener);
this.addEventListener(name, _listener);
});
return this; return this;
}; };

View file

@ -786,7 +786,7 @@ function bootstrapWorkerRuntime(
runtimeOptions, runtimeOptions,
name, name,
internalName, internalName,
maybeWorkerData, maybeWorkerMetadata,
) { ) {
if (hasBootstrapped) { if (hasBootstrapped) {
throw new Error("Worker runtime already bootstrapped"); throw new Error("Worker runtime already bootstrapped");
@ -909,17 +909,16 @@ function bootstrapWorkerRuntime(
// existing global `Deno` with `Deno` namespace from "./deno.ts". // existing global `Deno` with `Deno` namespace from "./deno.ts".
ObjectDefineProperty(globalThis, "Deno", core.propReadOnly(finalDenoNs)); ObjectDefineProperty(globalThis, "Deno", core.propReadOnly(finalDenoNs));
let workerData = undefined; const workerMetadata = maybeWorkerMetadata
if (maybeWorkerData) { ? messagePort.deserializeJsMessageData(maybeWorkerMetadata)
workerData = core.deserialize(maybeWorkerData); : undefined;
}
if (nodeBootstrap) { if (nodeBootstrap) {
nodeBootstrap( nodeBootstrap(
hasNodeModulesDir, hasNodeModulesDir,
argv0, argv0,
/* runningOnMainThread */ false, /* runningOnMainThread */ false,
workerData, workerMetadata,
); );
} }
} }

View file

@ -15,10 +15,8 @@ use crate::worker::FormatJsErrorFn;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;
use deno_core::serde::Deserialize; use deno_core::serde::Deserialize;
use deno_core::v8;
use deno_core::CancelFuture; use deno_core::CancelFuture;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::JsBuffer;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_core::OpState; use deno_core::OpState;
use deno_web::JsMessageData; use deno_web::JsMessageData;
@ -37,7 +35,7 @@ pub struct CreateWebWorkerArgs {
pub permissions: PermissionsContainer, pub permissions: PermissionsContainer,
pub main_module: ModuleSpecifier, pub main_module: ModuleSpecifier,
pub worker_type: WebWorkerType, pub worker_type: WebWorkerType,
pub maybe_worker_data: Option<Vec<u8>>, pub maybe_worker_metadata: Option<JsMessageData>,
} }
pub type CreateWebWorkerCb = dyn Fn(CreateWebWorkerArgs) -> (WebWorker, SendableWebWorkerHandle) pub type CreateWebWorkerCb = dyn Fn(CreateWebWorkerArgs) -> (WebWorker, SendableWebWorkerHandle)
@ -124,7 +122,7 @@ pub struct CreateWorkerArgs {
fn op_create_worker( fn op_create_worker(
state: &mut OpState, state: &mut OpState,
#[serde] args: CreateWorkerArgs, #[serde] args: CreateWorkerArgs,
#[buffer] maybe_worker_data: Option<JsBuffer>, #[serde] maybe_worker_metadata: Option<JsMessageData>,
) -> Result<WorkerId, AnyError> { ) -> Result<WorkerId, AnyError> {
let specifier = args.specifier.clone(); let specifier = args.specifier.clone();
let maybe_source_code = if args.has_source_code { let maybe_source_code = if args.has_source_code {
@ -178,7 +176,6 @@ fn op_create_worker(
// Setup new thread // Setup new thread
let thread_builder = std::thread::Builder::new().name(format!("{worker_id}")); let thread_builder = std::thread::Builder::new().name(format!("{worker_id}"));
let maybe_worker_data = maybe_worker_data.map(|buf| buf.to_vec());
// Spawn it // Spawn it
thread_builder.spawn(move || { thread_builder.spawn(move || {
// Any error inside this block is terminal: // Any error inside this block is terminal:
@ -194,7 +191,7 @@ fn op_create_worker(
permissions: worker_permissions, permissions: worker_permissions,
main_module: module_specifier.clone(), main_module: module_specifier.clone(),
worker_type, worker_type,
maybe_worker_data, maybe_worker_metadata,
}); });
// Send thread safe handle from newly created worker to host thread // Send thread safe handle from newly created worker to host thread

View file

@ -24,7 +24,6 @@ use deno_core::serde::Deserialize;
use deno_core::serde::Serialize; use deno_core::serde::Serialize;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::v8; use deno_core::v8;
use deno_core::v8::ValueDeserializerHelper;
use deno_core::CancelHandle; use deno_core::CancelHandle;
use deno_core::CompiledWasmModuleStore; use deno_core::CompiledWasmModuleStore;
use deno_core::Extension; use deno_core::Extension;
@ -49,6 +48,7 @@ use deno_terminal::colors;
use deno_tls::RootCertStoreProvider; use deno_tls::RootCertStoreProvider;
use deno_web::create_entangled_message_port; use deno_web::create_entangled_message_port;
use deno_web::BlobStore; use deno_web::BlobStore;
use deno_web::JsMessageData;
use deno_web::MessagePort; use deno_web::MessagePort;
use log::debug; use log::debug;
use std::cell::RefCell; use std::cell::RefCell;
@ -333,7 +333,7 @@ pub struct WebWorker {
poll_for_messages_fn: Option<v8::Global<v8::Value>>, poll_for_messages_fn: Option<v8::Global<v8::Value>>,
bootstrap_fn_global: Option<v8::Global<v8::Function>>, bootstrap_fn_global: Option<v8::Global<v8::Function>>,
// Consumed when `bootstrap_fn` is called // Consumed when `bootstrap_fn` is called
maybe_worker_data: Option<Vec<u8>>, maybe_worker_metadata: Option<JsMessageData>,
} }
pub struct WebWorkerOptions { pub struct WebWorkerOptions {
@ -359,7 +359,7 @@ pub struct WebWorkerOptions {
pub cache_storage_dir: Option<std::path::PathBuf>, pub cache_storage_dir: Option<std::path::PathBuf>,
pub stdio: Stdio, pub stdio: Stdio,
pub feature_checker: Arc<FeatureChecker>, pub feature_checker: Arc<FeatureChecker>,
pub maybe_worker_data: Option<Vec<u8>>, pub maybe_worker_metadata: Option<JsMessageData>,
} }
impl WebWorker { impl WebWorker {
@ -605,7 +605,7 @@ impl WebWorker {
main_module, main_module,
poll_for_messages_fn: None, poll_for_messages_fn: None,
bootstrap_fn_global: Some(bootstrap_fn_global), bootstrap_fn_global: Some(bootstrap_fn_global),
maybe_worker_data: options.maybe_worker_data, maybe_worker_metadata: options.maybe_worker_metadata,
}, },
external_handle, external_handle,
) )
@ -622,15 +622,8 @@ impl WebWorker {
let bootstrap_fn = v8::Local::new(scope, bootstrap_fn); let bootstrap_fn = v8::Local::new(scope, bootstrap_fn);
let undefined = v8::undefined(scope); let undefined = v8::undefined(scope);
let mut worker_data: v8::Local<v8::Value> = v8::undefined(scope).into(); let mut worker_data: v8::Local<v8::Value> = v8::undefined(scope).into();
if let Some(buf) = self.maybe_worker_data.take() { if let Some(data) = self.maybe_worker_metadata.take() {
let len = buf.len(); worker_data = deno_core::serde_v8::to_v8(scope, data).unwrap();
let store = v8::ArrayBuffer::new_backing_store_from_boxed_slice(
buf.into_boxed_slice(),
);
let ab =
v8::ArrayBuffer::with_backing_store(scope, &store.make_shared());
let v8_buf = v8::Uint8Array::new(scope, ab, 0, len).unwrap();
worker_data = v8_buf.into();
} }
let name_str: v8::Local<v8::Value> = let name_str: v8::Local<v8::Value> =
v8::String::new(scope, &self.name).unwrap().into(); v8::String::new(scope, &self.name).unwrap().into();