mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 07:44:48 -05:00
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
This commit is contained in:
parent
5294885a5a
commit
b424959d3e
2 changed files with 39 additions and 2 deletions
|
@ -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(
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
import { fromFileUrl, relative, SEPARATOR } from "@std/path/mod.ts";
|
||||
import * as workerThreads from "node:worker_threads";
|
||||
import { EventEmitter, once } from "node:events";
|
||||
import process from "node:process";
|
||||
|
||||
Deno.test("[node/worker_threads] BroadcastChannel is exported", () => {
|
||||
assertEquals<unknown>(workerThreads.BroadcastChannel, BroadcastChannel);
|
||||
|
@ -486,3 +487,31 @@ Deno.test({
|
|||
await worker.terminate();
|
||||
},
|
||||
});
|
||||
|
||||
Deno.test({
|
||||
name: "[node/worker_threads] Worker env using process.env",
|
||||
async fn() {
|
||||
const deferred = Promise.withResolvers<void>();
|
||||
const worker = new workerThreads.Worker(
|
||||
`
|
||||
import { parentPort } from "node:worker_threads";
|
||||
import process from "node:process";
|
||||
parentPort.postMessage("ok");
|
||||
`,
|
||||
{
|
||||
eval: true,
|
||||
// Make sure this doesn't throw `DataCloneError`.
|
||||
// See https://github.com/denoland/deno/issues/23522.
|
||||
env: process.env,
|
||||
},
|
||||
);
|
||||
|
||||
worker.on("message", (data) => {
|
||||
assertEquals(data, "ok");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
await deferred.promise;
|
||||
await worker.terminate();
|
||||
},
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue