From b424959d3e2554a83dd6a7a9c8837805a3d9ae65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 24 Apr 2024 17:17:28 +0100 Subject: fix(ext/node): worker_threads copies env object (#23536) Most common argument to `env` option for `worker_threads.Worker` will be `process.env`. In Deno `process.env` is a `Proxy` which can't be cloned using structured clone algorithm. So to be safe, I'm creating a copy of actual object before it's sent to the worker thread. Ref #23522 --- ext/node/polyfills/worker_threads.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'ext/node') diff --git a/ext/node/polyfills/worker_threads.ts b/ext/node/polyfills/worker_threads.ts index 96aa02fe1..8f531368a 100644 --- a/ext/node/polyfills/worker_threads.ts +++ b/ext/node/polyfills/worker_threads.ts @@ -29,7 +29,7 @@ import { EventEmitter } from "node:events"; import { BroadcastChannel } from "ext:deno_broadcast_channel/01_broadcast_channel.js"; import process from "node:process"; -const { ObjectPrototypeIsPrototypeOf } = primordials; +const { JSONParse, JSONStringify, ObjectPrototypeIsPrototypeOf } = primordials; const { Error, Symbol, @@ -126,10 +126,18 @@ class NodeWorker extends EventEmitter { } this.#name = name; + // One of the most common usages will be to pass `process.env` here, + // but because `process.env` is a Proxy in Deno, we need to get a plain + // object out of it - otherwise we'll run in `DataCloneError`s. + // See https://github.com/denoland/deno/issues/23522. + let env_ = undefined; + if (options?.env) { + env_ = JSONParse(JSONStringify(options?.env)); + } const serializedWorkerMetadata = serializeJsMessageData({ workerData: options?.workerData, environmentData: environmentData, - env: options?.env, + env: env_, }, options?.transferList ?? []); const id = op_create_worker( { -- cgit v1.2.3