Skip to content
File

Blob: src/node/worker_threads.ts

typescript203 lines
1// Copyright (c) 2017-2022 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5// Copyright Joyent, Inc. and other Node contributors.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a
8// copy of this software and associated documentation files (the
9// "Software"), to deal in the Software without restriction, including
10// without limitation the rights to use, copy, modify, merge, publish,
11// distribute, sublicense, and/or sell copies of the Software, and to permit
12// persons to whom the Software is furnished to do so, subject to the
13// following conditions:
14//
15// The above copyright notice and this permission notice shall be included
16// in all copies or substantial portions of the Software.
17//
18// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
21// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24// USE OR OTHER DEALINGS IN THE SOFTWARE.
25 
26import { ERR_METHOD_NOT_IMPLEMENTED } from 'node-internal:internal_errors';
27import { EventEmitter } from 'node-internal:events';
28import type {
29 ResourceLimits,
30 Serializable,
31 Worker as _Worker,
32} from 'node:worker_threads';
33import type { Context } from 'node:vm';
34import type { Readable, Writable } from 'node:stream';
35import type { Transferable, WorkerPerformance } from 'node:worker_threads';
36import type { CPUProfileHandle, HeapInfo, HeapProfileHandle } from 'node:v8';
37 
38// Import MessageChannel and MessagePort from the internal module to avoid
39// dependency on the expose_global_message_channel compatibility flag.
40import internalMessageChannel from 'cloudflare-internal:messagechannel';
41 
42export const MessageChannel = internalMessageChannel.MessageChannel;
43export const MessagePort = internalMessageChannel.MessagePort;
44 
45// TODO(soon): Use globalThis.BroadcastChannel once it's available.
46export class BroadcastChannel {
47 constructor() {
48 throw new ERR_METHOD_NOT_IMPLEMENTED('BroadcastChannel');
49 }
50}
51 
52export class Worker extends EventEmitter implements _Worker {
53 stdin: Writable | null = null;
54 stderr: Readable;
55 stdout: Readable;
56 threadId: number;
57 threadName: string = 'workerd';
58 performance: WorkerPerformance;
59 
60 constructor() {
61 super();
62 throw new ERR_METHOD_NOT_IMPLEMENTED('Worker');
63 }
64 
65 cpuUsage(_prev?: NodeJS.CpuUsage): Promise<NodeJS.CpuUsage> {
66 return Promise.reject(new ERR_METHOD_NOT_IMPLEMENTED('Worker.cpuUsage'));
67 }
68 
69 postMessage(_value: unknown, _transferList?: readonly Transferable[]): void {
70 // Acts as a no-op
71 }
72 
73 async postMessageToThread(
74 _threadId: unknown,
75 _value: unknown,
76 _transferList?: unknown,
77 _timeout?: unknown
78 ): Promise<void> {
79 // Acts as a noop.
80 }
81 
82 ref(): void {
83 // Acts as a noop.
84 }
85 
86 unref(): void {
87 // Acts as a noop.
88 }
89 
90 // eslint-disable-next-line @typescript-eslint/require-await
91 async terminate(): Promise<number> {
92 throw new ERR_METHOD_NOT_IMPLEMENTED('Worker.terminate');
93 }
94 
95 // eslint-disable-next-line @typescript-eslint/require-await
96 async getHeapSnapshot(): Promise<Readable> {
97 throw new ERR_METHOD_NOT_IMPLEMENTED('Worker.getHeapSnapshot');
98 }
99 
100 // eslint-disable-next-line @typescript-eslint/require-await
101 async getHeapStatistics(): Promise<HeapInfo> {
102 throw new ERR_METHOD_NOT_IMPLEMENTED('Worker.getHeapStatistics');
103 }
104 
105 // eslint-disable-next-line @typescript-eslint/require-await
106 async startCpuProfile(): Promise<CPUProfileHandle> {
107 throw new ERR_METHOD_NOT_IMPLEMENTED('Worker.startCpuProfile');
108 }
109 
110 // eslint-disable-next-line @typescript-eslint/require-await
111 async startHeapProfile(): Promise<HeapProfileHandle> {
112 throw new ERR_METHOD_NOT_IMPLEMENTED('Worker.startHeapProfile');
113 }
114 
115 async [Symbol.asyncDispose](): Promise<void> {
116 // Do nothing
117 }
118}
119 
120const environmentData = new Map<string, Serializable>();
121export function getEnvironmentData(key: string): Serializable | undefined {
122 return environmentData.get(key);
123}
124 
125export function setEnvironmentData(key: string, value: Serializable): void {
126 environmentData.set(key, value);
127}
128 
129export const isMainThread = true;
130 
131export function isMarkedAsUntransferable(_value: unknown): boolean {
132 return false;
133}
134 
135export function markAsUntransferable(_value: unknown): void {
136 // This is implement as a no-op.
137}
138 
139export function markAsUncloneable(_value: unknown): void {
140 // This is implement as a no-op.
141}
142 
143export function moveMessagePortToContext(
144 _port: MessagePort,
145 _contextifiedSandbox: Context
146): MessagePort {
147 return new MessagePort();
148}
149 
150export const parentPort: number | null = null;
151 
152export function receiveMessageOnPort(
153 _port: MessagePort
154): undefined | { message: unknown } {
155 return undefined;
156}
157 
158export const SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV');
159 
160export const resourceLimits: ResourceLimits = {};
161 
162export const threadId: number = 0;
163 
164export const workerData: Record<string, unknown> | null = null;
165 
166export function postMessageToThread(
167 threadId: number,
168 value: unknown,
169 timeout?: number
170): Promise<void>;
171export function postMessageToThread(
172 _threadId: number,
173 _value: unknown,
174 _transferList?: number | readonly Transferable[],
175 _timeout?: number
176): Promise<void> {
177 throw new ERR_METHOD_NOT_IMPLEMENTED('postMessageToThread');
178}
179 
180export const isInternalThread = false;
181 
182export default {
183 BroadcastChannel,
184 MessageChannel,
185 MessagePort,
186 Worker,
187 SHARE_ENV,
188 getEnvironmentData,
189 isMainThread,
190 isMarkedAsUntransferable,
191 markAsUntransferable,
192 markAsUncloneable,
193 moveMessagePortToContext,
194 parentPort,
195 receiveMessageOnPort,
196 resourceLimits,
197 setEnvironmentData,
198 postMessageToThread,
199 threadId,
200 workerData,
201 isInternalThread,
202};