UNPKG

8.19 kBTypeScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7/// <reference types="node" />
8
9import type {EventEmitter} from 'events';
10import type {ForkOptions} from 'child_process';
11import type {ResourceLimits} from 'worker_threads';
12
13declare const CHILD_MESSAGE_CALL = 1;
14
15declare const CHILD_MESSAGE_END = 2;
16
17declare const CHILD_MESSAGE_INITIALIZE = 0;
18
19declare type ChildMessage =
20 | ChildMessageInitialize
21 | ChildMessageCall
22 | ChildMessageEnd;
23
24declare type ChildMessageCall = [
25 typeof CHILD_MESSAGE_CALL,
26 boolean,
27 string,
28 Array<unknown>,
29];
30
31declare type ChildMessageEnd = [typeof CHILD_MESSAGE_END, boolean];
32
33declare type ChildMessageInitialize = [
34 typeof CHILD_MESSAGE_INITIALIZE,
35 boolean,
36 string,
37 // file
38 Array<unknown> | undefined,
39 // setupArgs
40 MessagePort_2 | undefined,
41];
42
43declare type ComputeTaskPriorityCallback = (
44 method: string,
45 ...args: Array<unknown>
46) => number;
47
48declare type ExcludeReservedKeys<K> = Exclude<K, ReservedKeys>;
49
50/**
51 * First-in, First-out task queue that manages a dedicated pool
52 * for each worker as well as a shared queue. The FIFO ordering is guaranteed
53 * across the worker specific and shared queue.
54 */
55export declare class FifoQueue implements TaskQueue {
56 private _workerQueues;
57 private _sharedQueue;
58 enqueue(task: QueueChildMessage, workerId?: number): void;
59 dequeue(workerId: number): QueueChildMessage | null;
60}
61
62declare type FunctionLike = (...args: any) => unknown;
63
64declare type HeapItem = {
65 priority: number;
66};
67
68export declare type JestWorkerFarm<T extends Record<string, unknown>> =
69 Worker_2 & WorkerModule<T>;
70
71export declare function messageParent(
72 message: unknown,
73 parentProcess?: NodeJS.Process,
74): void;
75
76declare type MessagePort_2 = typeof EventEmitter & {
77 postMessage(message: unknown): void;
78};
79
80declare type MethodLikeKeys<T> = {
81 [K in keyof T]: T[K] extends FunctionLike ? K : never;
82}[keyof T];
83
84declare class MinHeap<TItem extends HeapItem> {
85 private _heap;
86 peek(): TItem | null;
87 add(item: TItem): void;
88 poll(): TItem | null;
89}
90
91declare type OnCustomMessage = (message: Array<unknown> | unknown) => void;
92
93declare type OnEnd = (err: Error | null, result: unknown) => void;
94
95declare type OnStart = (worker: WorkerInterface) => void;
96
97declare type PoolExitResult = {
98 forceExited: boolean;
99};
100
101/**
102 * Priority queue that processes tasks in natural ordering (lower priority first)
103 * according to the priority computed by the function passed in the constructor.
104 *
105 * FIFO ordering isn't guaranteed for tasks with the same priority.
106 *
107 * Worker specific tasks with the same priority as a non-worker specific task
108 * are always processed first.
109 */
110export declare class PriorityQueue implements TaskQueue {
111 private _computePriority;
112 private _queue;
113 private _sharedQueue;
114 constructor(_computePriority: ComputeTaskPriorityCallback);
115 enqueue(task: QueueChildMessage, workerId?: number): void;
116 _enqueue(task: QueueChildMessage, queue: MinHeap<QueueItem>): void;
117 dequeue(workerId: number): QueueChildMessage | null;
118 _getWorkerQueue(workerId: number): MinHeap<QueueItem>;
119}
120
121export declare interface PromiseWithCustomMessage<T> extends Promise<T> {
122 UNSTABLE_onCustomMessage?: (listener: OnCustomMessage) => () => void;
123}
124
125declare type Promisify<T extends FunctionLike> = ReturnType<T> extends Promise<
126 infer R
127>
128 ? (...args: Parameters<T>) => Promise<R>
129 : (...args: Parameters<T>) => Promise<ReturnType<T>>;
130
131declare type QueueChildMessage = {
132 request: ChildMessageCall;
133 onStart: OnStart;
134 onEnd: OnEnd;
135 onCustomMessage: OnCustomMessage;
136};
137
138declare type QueueItem = {
139 task: QueueChildMessage;
140 priority: number;
141};
142
143declare type ReservedKeys =
144 | 'end'
145 | 'getStderr'
146 | 'getStdout'
147 | 'setup'
148 | 'teardown';
149
150export declare interface TaskQueue {
151 /**
152 * Enqueues the task in the queue for the specified worker or adds it to the
153 * queue shared by all workers
154 * @param task the task to queue
155 * @param workerId the id of the worker that should process this task or undefined
156 * if there's no preference.
157 */
158 enqueue(task: QueueChildMessage, workerId?: number): void;
159 /**
160 * Dequeues the next item from the queue for the specified worker
161 * @param workerId the id of the worker for which the next task should be retrieved
162 */
163 dequeue(workerId: number): QueueChildMessage | null;
164}
165
166/**
167 * The Jest farm (publicly called "Worker") is a class that allows you to queue
168 * methods across multiple child processes, in order to parallelize work. This
169 * is done by providing an absolute path to a module that will be loaded on each
170 * of the child processes, and bridged to the main process.
171 *
172 * Bridged methods are specified by using the "exposedMethods" property of the
173 * "options" object. This is an array of strings, where each of them corresponds
174 * to the exported name in the loaded module.
175 *
176 * You can also control the amount of workers by using the "numWorkers" property
177 * of the "options" object, and the settings passed to fork the process through
178 * the "forkOptions" property. The amount of workers defaults to the amount of
179 * CPUS minus one.
180 *
181 * Queueing calls can be done in two ways:
182 * - Standard method: calls will be redirected to the first available worker,
183 * so they will get executed as soon as they can.
184 *
185 * - Sticky method: if a "computeWorkerKey" method is provided within the
186 * config, the resulting string of this method will be used as a key.
187 * Every time this key is returned, it is guaranteed that your job will be
188 * processed by the same worker. This is specially useful if your workers
189 * are caching results.
190 */
191declare class Worker_2 {
192 private _ending;
193 private _farm;
194 private _options;
195 private _workerPool;
196 constructor(workerPath: string, options?: WorkerFarmOptions);
197 private _bindExposedWorkerMethods;
198 private _callFunctionWithArgs;
199 getStderr(): NodeJS.ReadableStream;
200 getStdout(): NodeJS.ReadableStream;
201 end(): Promise<PoolExitResult>;
202}
203export {Worker_2 as Worker};
204
205declare type WorkerCallback = (
206 workerId: number,
207 request: ChildMessage,
208 onStart: OnStart,
209 onEnd: OnEnd,
210 onCustomMessage: OnCustomMessage,
211) => void;
212
213export declare type WorkerFarmOptions = {
214 computeWorkerKey?: (method: string, ...args: Array<unknown>) => string | null;
215 enableWorkerThreads?: boolean;
216 exposedMethods?: ReadonlyArray<string>;
217 forkOptions?: ForkOptions;
218 maxRetries?: number;
219 numWorkers?: number;
220 resourceLimits?: ResourceLimits;
221 setupArgs?: Array<unknown>;
222 taskQueue?: TaskQueue;
223 WorkerPool?: new (
224 workerPath: string,
225 options?: WorkerPoolOptions,
226 ) => WorkerPoolInterface;
227 workerSchedulingPolicy?: WorkerSchedulingPolicy;
228};
229
230declare interface WorkerInterface {
231 send(
232 request: ChildMessage,
233 onProcessStart: OnStart,
234 onProcessEnd: OnEnd,
235 onCustomMessage: OnCustomMessage,
236 ): void;
237 waitForExit(): Promise<void>;
238 forceExit(): void;
239 getWorkerId(): number;
240 getStderr(): NodeJS.ReadableStream | null;
241 getStdout(): NodeJS.ReadableStream | null;
242}
243
244declare type WorkerModule<T> = {
245 [K in keyof T as Extract<
246 ExcludeReservedKeys<K>,
247 MethodLikeKeys<T>
248 >]: T[K] extends FunctionLike ? Promisify<T[K]> : never;
249};
250
251declare type WorkerOptions_2 = {
252 forkOptions: ForkOptions;
253 resourceLimits: ResourceLimits;
254 setupArgs: Array<unknown>;
255 maxRetries: number;
256 workerId: number;
257 workerData?: unknown;
258 workerPath: string;
259};
260
261export declare interface WorkerPoolInterface {
262 getStderr(): NodeJS.ReadableStream;
263 getStdout(): NodeJS.ReadableStream;
264 getWorkers(): Array<WorkerInterface>;
265 createWorker(options: WorkerOptions_2): WorkerInterface;
266 send: WorkerCallback;
267 end(): Promise<PoolExitResult>;
268}
269
270export declare type WorkerPoolOptions = {
271 setupArgs: Array<unknown>;
272 forkOptions: ForkOptions;
273 resourceLimits: ResourceLimits;
274 maxRetries: number;
275 numWorkers: number;
276 enableWorkerThreads: boolean;
277};
278
279declare type WorkerSchedulingPolicy = 'round-robin' | 'in-order';
280
281export {};