mirror of
https://github.com/denoland/deno.git
synced 2024-11-23 15:16:54 -05:00
populate data on bootstrap
This commit is contained in:
parent
c19a9d9794
commit
7d7ebef4e2
6 changed files with 39 additions and 74 deletions
|
@ -841,7 +841,7 @@ fn create_web_worker_callback(
|
|||
stdio: stdio.clone(),
|
||||
cache_storage_dir,
|
||||
feature_checker,
|
||||
maybe_worker_data: args.maybe_worker_data,
|
||||
maybe_worker_metadata: args.maybe_worker_metadata,
|
||||
};
|
||||
|
||||
WebWorker::bootstrap_from_options(
|
||||
|
|
|
@ -14,7 +14,7 @@ function initialize(
|
|||
usesLocalNodeModulesDir,
|
||||
argv0,
|
||||
runningOnMainThread,
|
||||
maybeWorkerData,
|
||||
maybeWorkerMetadata,
|
||||
) {
|
||||
if (initialized) {
|
||||
throw Error("Node runtime already initialized");
|
||||
|
@ -39,7 +39,7 @@ function initialize(
|
|||
// FIXME(bartlomieju): not nice to depend on `Deno` namespace here
|
||||
// but it's the only way to get `args` and `version` and this point.
|
||||
internals.__bootstrapNodeProcess(argv0, Deno.args, Deno.version);
|
||||
internals.__initWorkerThreads(runningOnMainThread, maybeWorkerData);
|
||||
internals.__initWorkerThreads(runningOnMainThread, maybeWorkerMetadata);
|
||||
internals.__setupChildProcessIpcChannel();
|
||||
// `Deno[Deno.internal].requireImpl` will be unreachable after this line.
|
||||
delete internals.requireImpl;
|
||||
|
|
|
@ -22,7 +22,7 @@ import {
|
|||
import * as webidl from "ext:deno_webidl/00_webidl.js";
|
||||
import { log } from "ext:runtime/06_util.js";
|
||||
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 { isAbsolute, resolve } from "node:path";
|
||||
|
||||
|
@ -42,7 +42,6 @@ const {
|
|||
SafeRegExp,
|
||||
SafeMap,
|
||||
TypeError,
|
||||
PromisePrototypeThen,
|
||||
} = primordials;
|
||||
|
||||
export interface WorkerOptions {
|
||||
|
@ -196,12 +195,13 @@ class NodeWorker extends EventEmitter {
|
|||
name = "[worker eval]";
|
||||
}
|
||||
this.#name = name;
|
||||
this.threadId = ++threads;
|
||||
|
||||
const maybeWorkerData = options?.workerData;
|
||||
const serializedWorkerData = maybeWorkerData
|
||||
? core.serialize(maybeWorkerData)
|
||||
: undefined;
|
||||
|
||||
const serializedWorkerMetadata = serializeJsMessageData({
|
||||
workerData: options?.workerData,
|
||||
environmentData: environmentData,
|
||||
threadId: this.threadId,
|
||||
}, options?.transferList ?? []);
|
||||
const id = op_create_worker(
|
||||
{
|
||||
// deno-lint-ignore prefer-primordials
|
||||
|
@ -212,15 +212,11 @@ class NodeWorker extends EventEmitter {
|
|||
name: this.#name,
|
||||
workerType: "module",
|
||||
},
|
||||
serializedWorkerMetadata,
|
||||
);
|
||||
this.#id = id;
|
||||
this.#pollControl();
|
||||
this.#pollMessages();
|
||||
|
||||
this.postMessage({
|
||||
environmentData,
|
||||
threadId: (this.threadId = ++threads),
|
||||
}, options?.transferList || []);
|
||||
// https://nodejs.org/api/worker_threads.html#event-online
|
||||
this.emit("online");
|
||||
}
|
||||
|
@ -394,7 +390,7 @@ let parentPort: ParentPort = null as any;
|
|||
|
||||
internals.__initWorkerThreads = (
|
||||
runningOnMainThread: boolean,
|
||||
maybeWorkerData,
|
||||
maybeWorkerMetadata,
|
||||
) => {
|
||||
isMainThread = runningOnMainThread;
|
||||
|
||||
|
@ -417,29 +413,13 @@ internals.__initWorkerThreads = (
|
|||
>();
|
||||
|
||||
parentPort = self as ParentPort;
|
||||
workerData = maybeWorkerData;
|
||||
const { 0: metadata, 1: _ } = maybeWorkerMetadata;
|
||||
workerData = metadata.workerData;
|
||||
environmentData = metadata.environmentData;
|
||||
threadId = metadata.threadId;
|
||||
defaultExport.workerData = workerData;
|
||||
defaultExport.parentPort = parentPort;
|
||||
|
||||
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;
|
||||
},
|
||||
);
|
||||
defaultExport.threadId = threadId;
|
||||
|
||||
parentPort.off = parentPort.removeListener = function (
|
||||
this: ParentPort,
|
||||
|
@ -455,22 +435,18 @@ internals.__initWorkerThreads = (
|
|||
name,
|
||||
listener,
|
||||
) {
|
||||
PromisePrototypeThen(initPromise, () => {
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const _listener = (ev: any) => listener(ev.data);
|
||||
listeners.set(listener, _listener);
|
||||
this.addEventListener(name, _listener);
|
||||
});
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const _listener = (ev: any) => listener(ev.data);
|
||||
listeners.set(listener, _listener);
|
||||
this.addEventListener(name, _listener);
|
||||
return this;
|
||||
};
|
||||
|
||||
parentPort.once = function (this: ParentPort, name, listener) {
|
||||
PromisePrototypeThen(initPromise, () => {
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const _listener = (ev: any) => listener(ev.data);
|
||||
listeners.set(listener, _listener);
|
||||
this.addEventListener(name, _listener);
|
||||
});
|
||||
// deno-lint-ignore no-explicit-any
|
||||
const _listener = (ev: any) => listener(ev.data);
|
||||
listeners.set(listener, _listener);
|
||||
this.addEventListener(name, _listener);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
|
|
@ -786,7 +786,7 @@ function bootstrapWorkerRuntime(
|
|||
runtimeOptions,
|
||||
name,
|
||||
internalName,
|
||||
maybeWorkerData,
|
||||
maybeWorkerMetadata,
|
||||
) {
|
||||
if (hasBootstrapped) {
|
||||
throw new Error("Worker runtime already bootstrapped");
|
||||
|
@ -909,17 +909,16 @@ function bootstrapWorkerRuntime(
|
|||
// existing global `Deno` with `Deno` namespace from "./deno.ts".
|
||||
ObjectDefineProperty(globalThis, "Deno", core.propReadOnly(finalDenoNs));
|
||||
|
||||
let workerData = undefined;
|
||||
if (maybeWorkerData) {
|
||||
workerData = core.deserialize(maybeWorkerData);
|
||||
}
|
||||
const workerMetadata = maybeWorkerMetadata
|
||||
? messagePort.deserializeJsMessageData(maybeWorkerMetadata)
|
||||
: undefined;
|
||||
|
||||
if (nodeBootstrap) {
|
||||
nodeBootstrap(
|
||||
hasNodeModulesDir,
|
||||
argv0,
|
||||
/* runningOnMainThread */ false,
|
||||
workerData,
|
||||
workerMetadata,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,8 @@ use crate::worker::FormatJsErrorFn;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::v8;
|
||||
use deno_core::CancelFuture;
|
||||
use deno_core::CancelHandle;
|
||||
use deno_core::JsBuffer;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_web::JsMessageData;
|
||||
|
@ -37,7 +35,7 @@ pub struct CreateWebWorkerArgs {
|
|||
pub permissions: PermissionsContainer,
|
||||
pub main_module: ModuleSpecifier,
|
||||
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)
|
||||
|
@ -124,7 +122,7 @@ pub struct CreateWorkerArgs {
|
|||
fn op_create_worker(
|
||||
state: &mut OpState,
|
||||
#[serde] args: CreateWorkerArgs,
|
||||
#[buffer] maybe_worker_data: Option<JsBuffer>,
|
||||
#[serde] maybe_worker_metadata: Option<JsMessageData>,
|
||||
) -> Result<WorkerId, AnyError> {
|
||||
let specifier = args.specifier.clone();
|
||||
let maybe_source_code = if args.has_source_code {
|
||||
|
@ -178,7 +176,6 @@ fn op_create_worker(
|
|||
// Setup new thread
|
||||
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
|
||||
thread_builder.spawn(move || {
|
||||
// Any error inside this block is terminal:
|
||||
|
@ -194,7 +191,7 @@ fn op_create_worker(
|
|||
permissions: worker_permissions,
|
||||
main_module: module_specifier.clone(),
|
||||
worker_type,
|
||||
maybe_worker_data,
|
||||
maybe_worker_metadata,
|
||||
});
|
||||
|
||||
// Send thread safe handle from newly created worker to host thread
|
||||
|
|
|
@ -24,7 +24,6 @@ use deno_core::serde::Deserialize;
|
|||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::v8;
|
||||
use deno_core::v8::ValueDeserializerHelper;
|
||||
use deno_core::CancelHandle;
|
||||
use deno_core::CompiledWasmModuleStore;
|
||||
use deno_core::Extension;
|
||||
|
@ -49,6 +48,7 @@ use deno_terminal::colors;
|
|||
use deno_tls::RootCertStoreProvider;
|
||||
use deno_web::create_entangled_message_port;
|
||||
use deno_web::BlobStore;
|
||||
use deno_web::JsMessageData;
|
||||
use deno_web::MessagePort;
|
||||
use log::debug;
|
||||
use std::cell::RefCell;
|
||||
|
@ -333,7 +333,7 @@ pub struct WebWorker {
|
|||
poll_for_messages_fn: Option<v8::Global<v8::Value>>,
|
||||
bootstrap_fn_global: Option<v8::Global<v8::Function>>,
|
||||
// Consumed when `bootstrap_fn` is called
|
||||
maybe_worker_data: Option<Vec<u8>>,
|
||||
maybe_worker_metadata: Option<JsMessageData>,
|
||||
}
|
||||
|
||||
pub struct WebWorkerOptions {
|
||||
|
@ -359,7 +359,7 @@ pub struct WebWorkerOptions {
|
|||
pub cache_storage_dir: Option<std::path::PathBuf>,
|
||||
pub stdio: Stdio,
|
||||
pub feature_checker: Arc<FeatureChecker>,
|
||||
pub maybe_worker_data: Option<Vec<u8>>,
|
||||
pub maybe_worker_metadata: Option<JsMessageData>,
|
||||
}
|
||||
|
||||
impl WebWorker {
|
||||
|
@ -605,7 +605,7 @@ impl WebWorker {
|
|||
main_module,
|
||||
poll_for_messages_fn: None,
|
||||
bootstrap_fn_global: Some(bootstrap_fn_global),
|
||||
maybe_worker_data: options.maybe_worker_data,
|
||||
maybe_worker_metadata: options.maybe_worker_metadata,
|
||||
},
|
||||
external_handle,
|
||||
)
|
||||
|
@ -622,15 +622,8 @@ impl WebWorker {
|
|||
let bootstrap_fn = v8::Local::new(scope, bootstrap_fn);
|
||||
let undefined = v8::undefined(scope);
|
||||
let mut worker_data: v8::Local<v8::Value> = v8::undefined(scope).into();
|
||||
if let Some(buf) = self.maybe_worker_data.take() {
|
||||
let len = buf.len();
|
||||
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();
|
||||
if let Some(data) = self.maybe_worker_metadata.take() {
|
||||
worker_data = deno_core::serde_v8::to_v8(scope, data).unwrap();
|
||||
}
|
||||
let name_str: v8::Local<v8::Value> =
|
||||
v8::String::new(scope, &self.name).unwrap().into();
|
||||
|
|
Loading…
Reference in a new issue