forked from daren.hsu/line_push
update
This commit is contained in:
+2
-2
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
import { FarmOptions } from './types';
|
||||
import { FarmOptions, PromiseWithCustomMessage } from './types';
|
||||
export default class Farm {
|
||||
private _computeWorkerKey;
|
||||
private _cacheKeys;
|
||||
@@ -15,7 +15,7 @@ export default class Farm {
|
||||
private _offset;
|
||||
private _queue;
|
||||
constructor(numOfWorkers: number, callback: Function, computeWorkerKey?: FarmOptions['computeWorkerKey']);
|
||||
doWork(method: string, ...args: Array<any>): Promise<unknown>;
|
||||
doWork(method: string, ...args: Array<unknown>): PromiseWithCustomMessage<unknown>;
|
||||
private _getNextTask;
|
||||
private _process;
|
||||
private _enqueue;
|
||||
|
||||
+26
-2
@@ -53,7 +53,20 @@ class Farm {
|
||||
}
|
||||
|
||||
doWork(method, ...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const customMessageListeners = new Set();
|
||||
|
||||
const addCustomMessageListener = listener => {
|
||||
customMessageListeners.add(listener);
|
||||
return () => {
|
||||
customMessageListeners.delete(listener);
|
||||
};
|
||||
};
|
||||
|
||||
const onCustomMessage = message => {
|
||||
customMessageListeners.forEach(listener => listener(message));
|
||||
};
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
const computeWorkerKey = this._computeWorkerKey;
|
||||
const request = [_types.CHILD_MESSAGE_CALL, false, method, args];
|
||||
let worker = null;
|
||||
@@ -71,6 +84,8 @@ class Farm {
|
||||
};
|
||||
|
||||
const onEnd = (error, result) => {
|
||||
customMessageListeners.clear();
|
||||
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
@@ -79,6 +94,7 @@ class Farm {
|
||||
};
|
||||
|
||||
const task = {
|
||||
onCustomMessage,
|
||||
onEnd,
|
||||
onStart,
|
||||
request
|
||||
@@ -90,6 +106,8 @@ class Farm {
|
||||
this._push(task);
|
||||
}
|
||||
});
|
||||
promise.UNSTABLE_onCustomMessage = addCustomMessageListener;
|
||||
return promise;
|
||||
}
|
||||
|
||||
_getNextTask(workerId) {
|
||||
@@ -126,7 +144,13 @@ class Farm {
|
||||
|
||||
this._lock(workerId);
|
||||
|
||||
this._callback(workerId, task.request, task.onStart, onEnd);
|
||||
this._callback(
|
||||
workerId,
|
||||
task.request,
|
||||
task.onStart,
|
||||
onEnd,
|
||||
task.onCustomMessage
|
||||
);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,9 +5,9 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
import BaseWorkerPool from './base/BaseWorkerPool';
|
||||
import type { ChildMessage, OnEnd, OnStart, WorkerInterface, WorkerOptions, WorkerPoolInterface } from './types';
|
||||
import type { ChildMessage, OnCustomMessage, OnEnd, OnStart, WorkerInterface, WorkerOptions, WorkerPoolInterface } from './types';
|
||||
declare class WorkerPool extends BaseWorkerPool implements WorkerPoolInterface {
|
||||
send(workerId: number, request: ChildMessage, onStart: OnStart, onEnd: OnEnd): void;
|
||||
send(workerId: number, request: ChildMessage, onStart: OnStart, onEnd: OnEnd, onCustomMessage: OnCustomMessage): void;
|
||||
createWorker(workerOptions: WorkerOptions): WorkerInterface;
|
||||
}
|
||||
export default WorkerPool;
|
||||
|
||||
+3
-3
@@ -22,14 +22,14 @@ const canUseWorkerThreads = () => {
|
||||
require('worker_threads');
|
||||
|
||||
return true;
|
||||
} catch (_unused) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class WorkerPool extends _BaseWorkerPool.default {
|
||||
send(workerId, request, onStart, onEnd) {
|
||||
this.getWorkerById(workerId).send(request, onStart, onEnd);
|
||||
send(workerId, request, onStart, onEnd, onCustomMessage) {
|
||||
this.getWorkerById(workerId).send(request, onStart, onEnd, onCustomMessage);
|
||||
}
|
||||
|
||||
createWorker(workerOptions) {
|
||||
|
||||
+3
-1
@@ -121,12 +121,13 @@ class BaseWorkerPool {
|
||||
|
||||
const stdout = (0, _mergeStream().default)();
|
||||
const stderr = (0, _mergeStream().default)();
|
||||
const {forkOptions, maxRetries, setupArgs} = options;
|
||||
const {forkOptions, maxRetries, resourceLimits, setupArgs} = options;
|
||||
|
||||
for (let i = 0; i < options.numWorkers; i++) {
|
||||
const workerOptions = {
|
||||
forkOptions,
|
||||
maxRetries,
|
||||
resourceLimits,
|
||||
setupArgs,
|
||||
workerId: i,
|
||||
workerPath
|
||||
@@ -177,6 +178,7 @@ class BaseWorkerPool {
|
||||
worker.send(
|
||||
[_types().CHILD_MESSAGE_END, false],
|
||||
emptyMethod,
|
||||
emptyMethod,
|
||||
emptyMethod
|
||||
); // Schedule a force exit in case worker fails to exit gracefully so
|
||||
// await worker.waitForExit() never takes longer than FORCE_EXIT_DELAY
|
||||
|
||||
+3
-1
@@ -5,7 +5,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/// <reference types="node" />
|
||||
import type { FarmOptions, PoolExitResult } from './types';
|
||||
import type { FarmOptions, PoolExitResult, PromiseWithCustomMessage } from './types';
|
||||
export { default as messageParent } from './workers/messageParent';
|
||||
/**
|
||||
* The Jest farm (publicly called "Worker") is a class that allows you to queue
|
||||
* methods across multiple child processes, in order to parallelize work. This
|
||||
@@ -43,3 +44,4 @@ export default class JestWorker {
|
||||
getStdout(): NodeJS.ReadableStream;
|
||||
end(): Promise<PoolExitResult>;
|
||||
}
|
||||
export type { PromiseWithCustomMessage };
|
||||
|
||||
+48
-9
@@ -3,6 +3,12 @@
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, 'messageParent', {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _messageParent.default;
|
||||
}
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
function _os() {
|
||||
@@ -15,9 +21,11 @@ function _os() {
|
||||
return data;
|
||||
}
|
||||
|
||||
var _Farm = _interopRequireDefault(require('./Farm'));
|
||||
|
||||
var _WorkerPool = _interopRequireDefault(require('./WorkerPool'));
|
||||
|
||||
var _Farm = _interopRequireDefault(require('./Farm'));
|
||||
var _messageParent = _interopRequireDefault(require('./workers/messageParent'));
|
||||
|
||||
function _interopRequireDefault(obj) {
|
||||
return obj && obj.__esModule ? obj : {default: obj};
|
||||
@@ -44,7 +52,7 @@ function getExposedMethods(workerPath, options) {
|
||||
const module = require(workerPath);
|
||||
|
||||
exposedMethods = Object.keys(module).filter(
|
||||
// @ts-ignore: no index
|
||||
// @ts-expect-error: no index
|
||||
name => typeof module[name] === 'function'
|
||||
);
|
||||
|
||||
@@ -83,6 +91,13 @@ function getExposedMethods(workerPath, options) {
|
||||
|
||||
class JestWorker {
|
||||
constructor(workerPath, options) {
|
||||
var _this$_options$enable,
|
||||
_this$_options$forkOp,
|
||||
_this$_options$maxRet,
|
||||
_this$_options$numWor,
|
||||
_this$_options$resour,
|
||||
_this$_options$setupA;
|
||||
|
||||
_defineProperty(this, '_ending', void 0);
|
||||
|
||||
_defineProperty(this, '_farm', void 0);
|
||||
@@ -94,16 +109,40 @@ class JestWorker {
|
||||
this._options = {...options};
|
||||
this._ending = false;
|
||||
const workerPoolOptions = {
|
||||
enableWorkerThreads: this._options.enableWorkerThreads || false,
|
||||
forkOptions: this._options.forkOptions || {},
|
||||
maxRetries: this._options.maxRetries || 3,
|
||||
enableWorkerThreads:
|
||||
(_this$_options$enable = this._options.enableWorkerThreads) !== null &&
|
||||
_this$_options$enable !== void 0
|
||||
? _this$_options$enable
|
||||
: false,
|
||||
forkOptions:
|
||||
(_this$_options$forkOp = this._options.forkOptions) !== null &&
|
||||
_this$_options$forkOp !== void 0
|
||||
? _this$_options$forkOp
|
||||
: {},
|
||||
maxRetries:
|
||||
(_this$_options$maxRet = this._options.maxRetries) !== null &&
|
||||
_this$_options$maxRet !== void 0
|
||||
? _this$_options$maxRet
|
||||
: 3,
|
||||
numWorkers:
|
||||
this._options.numWorkers || Math.max((0, _os().cpus)().length - 1, 1),
|
||||
setupArgs: this._options.setupArgs || []
|
||||
(_this$_options$numWor = this._options.numWorkers) !== null &&
|
||||
_this$_options$numWor !== void 0
|
||||
? _this$_options$numWor
|
||||
: Math.max((0, _os().cpus)().length - 1, 1),
|
||||
resourceLimits:
|
||||
(_this$_options$resour = this._options.resourceLimits) !== null &&
|
||||
_this$_options$resour !== void 0
|
||||
? _this$_options$resour
|
||||
: {},
|
||||
setupArgs:
|
||||
(_this$_options$setupA = this._options.setupArgs) !== null &&
|
||||
_this$_options$setupA !== void 0
|
||||
? _this$_options$setupA
|
||||
: []
|
||||
};
|
||||
|
||||
if (this._options.WorkerPool) {
|
||||
// @ts-ignore: constructor target any?
|
||||
// @ts-expect-error: constructor target any?
|
||||
this._workerPool = new this._options.WorkerPool(
|
||||
workerPath,
|
||||
workerPoolOptions
|
||||
@@ -129,7 +168,7 @@ class JestWorker {
|
||||
|
||||
if (this.constructor.prototype.hasOwnProperty(name)) {
|
||||
throw new TypeError('Cannot define a method called ' + name);
|
||||
} // @ts-ignore: dynamic extension of the class instance is expected.
|
||||
} // @ts-expect-error: dynamic extension of the class instance is expected.
|
||||
|
||||
this[name] = this._callFunctionWithArgs.bind(this, name);
|
||||
});
|
||||
|
||||
+52
-24
@@ -5,25 +5,31 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/// <reference types="node" />
|
||||
import type { EventEmitter } from 'events';
|
||||
import type { ForkOptions } from 'child_process';
|
||||
import type { EventEmitter } from 'events';
|
||||
export interface ResourceLimits {
|
||||
maxYoungGenerationSizeMb?: number;
|
||||
maxOldGenerationSizeMb?: number;
|
||||
codeRangeSizeMb?: number;
|
||||
}
|
||||
export declare const CHILD_MESSAGE_INITIALIZE: 0;
|
||||
export declare const CHILD_MESSAGE_CALL: 1;
|
||||
export declare const CHILD_MESSAGE_END: 2;
|
||||
export declare const PARENT_MESSAGE_OK: 0;
|
||||
export declare const PARENT_MESSAGE_CLIENT_ERROR: 1;
|
||||
export declare const PARENT_MESSAGE_SETUP_ERROR: 2;
|
||||
export declare const PARENT_MESSAGE_CUSTOM: 3;
|
||||
export declare type PARENT_MESSAGE_ERROR = typeof PARENT_MESSAGE_CLIENT_ERROR | typeof PARENT_MESSAGE_SETUP_ERROR;
|
||||
export interface WorkerPoolInterface {
|
||||
getStderr(): NodeJS.ReadableStream;
|
||||
getStdout(): NodeJS.ReadableStream;
|
||||
getWorkers(): Array<WorkerInterface>;
|
||||
createWorker(options: WorkerOptions): WorkerInterface;
|
||||
send(workerId: number, request: ChildMessage, onStart: OnStart, onEnd: OnEnd): void;
|
||||
send(workerId: number, request: ChildMessage, onStart: OnStart, onEnd: OnEnd, onCustomMessage: OnCustomMessage): void;
|
||||
end(): Promise<PoolExitResult>;
|
||||
}
|
||||
export interface WorkerInterface {
|
||||
send(request: ChildMessage, onProcessStart: OnStart, onProcessEnd: OnEnd): void;
|
||||
send(request: ChildMessage, onProcessStart: OnStart, onProcessEnd: OnEnd, onCustomMessage: OnCustomMessage): void;
|
||||
waitForExit(): Promise<void>;
|
||||
forceExit(): void;
|
||||
getWorkerId(): number;
|
||||
@@ -33,11 +39,15 @@ export interface WorkerInterface {
|
||||
export declare type PoolExitResult = {
|
||||
forceExited: boolean;
|
||||
};
|
||||
export interface PromiseWithCustomMessage<T> extends Promise<T> {
|
||||
UNSTABLE_onCustomMessage?: (listener: OnCustomMessage) => () => void;
|
||||
}
|
||||
export type { ForkOptions };
|
||||
export declare type FarmOptions = {
|
||||
computeWorkerKey?: (method: string, ...args: Array<unknown>) => string | null;
|
||||
exposedMethods?: ReadonlyArray<string>;
|
||||
forkOptions?: ForkOptions;
|
||||
resourceLimits?: ResourceLimits;
|
||||
setupArgs?: Array<unknown>;
|
||||
maxRetries?: number;
|
||||
numWorkers?: number;
|
||||
@@ -47,12 +57,14 @@ export declare type FarmOptions = {
|
||||
export declare type WorkerPoolOptions = {
|
||||
setupArgs: Array<unknown>;
|
||||
forkOptions: ForkOptions;
|
||||
resourceLimits: ResourceLimits;
|
||||
maxRetries: number;
|
||||
numWorkers: number;
|
||||
enableWorkerThreads: boolean;
|
||||
};
|
||||
export declare type WorkerOptions = {
|
||||
forkOptions: ForkOptions;
|
||||
resourceLimits: ResourceLimits;
|
||||
setupArgs: Array<unknown>;
|
||||
maxRetries: number;
|
||||
workerId: number;
|
||||
@@ -65,34 +77,50 @@ export declare type MessageChannel = {
|
||||
port1: MessagePort;
|
||||
port2: MessagePort;
|
||||
};
|
||||
export declare type ChildMessageInitialize = [typeof CHILD_MESSAGE_INITIALIZE, // type
|
||||
boolean, // processed
|
||||
string, // file
|
||||
// file
|
||||
Array<unknown> | undefined, // setupArgs
|
||||
// setupArgs
|
||||
MessagePort | undefined];
|
||||
export declare type ChildMessageCall = [typeof CHILD_MESSAGE_CALL, // type
|
||||
boolean, // processed
|
||||
string, // method
|
||||
Array<unknown>];
|
||||
export declare type ChildMessageEnd = [typeof CHILD_MESSAGE_END, // type
|
||||
boolean];
|
||||
export declare type ChildMessageInitialize = [
|
||||
typeof CHILD_MESSAGE_INITIALIZE,
|
||||
boolean,
|
||||
string,
|
||||
// file
|
||||
Array<unknown> | undefined,
|
||||
// setupArgs
|
||||
MessagePort | undefined
|
||||
];
|
||||
export declare type ChildMessageCall = [
|
||||
typeof CHILD_MESSAGE_CALL,
|
||||
boolean,
|
||||
string,
|
||||
Array<unknown>
|
||||
];
|
||||
export declare type ChildMessageEnd = [
|
||||
typeof CHILD_MESSAGE_END,
|
||||
boolean
|
||||
];
|
||||
export declare type ChildMessage = ChildMessageInitialize | ChildMessageCall | ChildMessageEnd;
|
||||
export declare type ParentMessageOk = [typeof PARENT_MESSAGE_OK, // type
|
||||
unknown];
|
||||
export declare type ParentMessageError = [PARENT_MESSAGE_ERROR, // type
|
||||
string, // constructor
|
||||
string, // message
|
||||
string, // stack
|
||||
unknown];
|
||||
export declare type ParentMessage = ParentMessageOk | ParentMessageError;
|
||||
export declare type ParentMessageCustom = [
|
||||
typeof PARENT_MESSAGE_CUSTOM,
|
||||
unknown
|
||||
];
|
||||
export declare type ParentMessageOk = [
|
||||
typeof PARENT_MESSAGE_OK,
|
||||
unknown
|
||||
];
|
||||
export declare type ParentMessageError = [
|
||||
PARENT_MESSAGE_ERROR,
|
||||
string,
|
||||
string,
|
||||
string,
|
||||
unknown
|
||||
];
|
||||
export declare type ParentMessage = ParentMessageOk | ParentMessageError | ParentMessageCustom;
|
||||
export declare type OnStart = (worker: WorkerInterface) => void;
|
||||
export declare type OnEnd = (err: Error | null, result: unknown) => void;
|
||||
export declare type OnCustomMessage = (message: Array<unknown> | unknown) => void;
|
||||
export declare type QueueChildMessage = {
|
||||
request: ChildMessage;
|
||||
onStart: OnStart;
|
||||
onEnd: OnEnd;
|
||||
onCustomMessage: OnCustomMessage;
|
||||
};
|
||||
export declare type QueueItem = {
|
||||
task: QueueChildMessage;
|
||||
|
||||
+5
-1
@@ -3,7 +3,7 @@
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
exports.PARENT_MESSAGE_SETUP_ERROR = exports.PARENT_MESSAGE_CLIENT_ERROR = exports.PARENT_MESSAGE_OK = exports.CHILD_MESSAGE_END = exports.CHILD_MESSAGE_CALL = exports.CHILD_MESSAGE_INITIALIZE = void 0;
|
||||
exports.PARENT_MESSAGE_CUSTOM = exports.PARENT_MESSAGE_SETUP_ERROR = exports.PARENT_MESSAGE_CLIENT_ERROR = exports.PARENT_MESSAGE_OK = exports.CHILD_MESSAGE_END = exports.CHILD_MESSAGE_CALL = exports.CHILD_MESSAGE_INITIALIZE = void 0;
|
||||
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
||||
@@ -11,6 +11,8 @@ exports.PARENT_MESSAGE_SETUP_ERROR = exports.PARENT_MESSAGE_CLIENT_ERROR = expor
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
// import type {ResourceLimits} from 'worker_threads';
|
||||
// This is not present in the Node 12 typings
|
||||
// Because of the dynamic nature of a worker communication process, all messages
|
||||
// coming from any of the other processes cannot be typed. Thus, many types
|
||||
// include "unknown" as a TS type, which is (unfortunately) correct here.
|
||||
@@ -26,3 +28,5 @@ const PARENT_MESSAGE_CLIENT_ERROR = 1;
|
||||
exports.PARENT_MESSAGE_CLIENT_ERROR = PARENT_MESSAGE_CLIENT_ERROR;
|
||||
const PARENT_MESSAGE_SETUP_ERROR = 2;
|
||||
exports.PARENT_MESSAGE_SETUP_ERROR = PARENT_MESSAGE_SETUP_ERROR;
|
||||
const PARENT_MESSAGE_CUSTOM = 3;
|
||||
exports.PARENT_MESSAGE_CUSTOM = PARENT_MESSAGE_CUSTOM;
|
||||
|
||||
+3
-2
@@ -5,7 +5,7 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/// <reference types="node" />
|
||||
import { ChildMessage, OnEnd, OnStart, WorkerInterface, WorkerOptions } from '../types';
|
||||
import { ChildMessage, OnCustomMessage, OnEnd, OnStart, WorkerInterface, WorkerOptions } from '../types';
|
||||
/**
|
||||
* This class wraps the child process and provides a nice interface to
|
||||
* communicate with. It takes care of:
|
||||
@@ -30,6 +30,7 @@ export default class ChildProcessWorker implements WorkerInterface {
|
||||
private _request;
|
||||
private _retries;
|
||||
private _onProcessEnd;
|
||||
private _onCustomMessage;
|
||||
private _fakeStream;
|
||||
private _stdout;
|
||||
private _stderr;
|
||||
@@ -40,7 +41,7 @@ export default class ChildProcessWorker implements WorkerInterface {
|
||||
private _shutdown;
|
||||
private _onMessage;
|
||||
private _onExit;
|
||||
send(request: ChildMessage, onProcessStart: OnStart, onProcessEnd: OnEnd): void;
|
||||
send(request: ChildMessage, onProcessStart: OnStart, onProcessEnd: OnEnd, onCustomMessage: OnCustomMessage): void;
|
||||
waitForExit(): Promise<void>;
|
||||
forceExit(): void;
|
||||
getWorkerId(): number;
|
||||
|
||||
+13
-5
@@ -109,6 +109,8 @@ class ChildProcessWorker {
|
||||
|
||||
_defineProperty(this, '_onProcessEnd', void 0);
|
||||
|
||||
_defineProperty(this, '_onCustomMessage', void 0);
|
||||
|
||||
_defineProperty(this, '_fakeStream', void 0);
|
||||
|
||||
_defineProperty(this, '_stdout', void 0);
|
||||
@@ -214,6 +216,7 @@ class ChildProcessWorker {
|
||||
}
|
||||
|
||||
_onMessage(response) {
|
||||
// TODO: Add appropriate type check
|
||||
let error;
|
||||
|
||||
switch (response[0]) {
|
||||
@@ -226,7 +229,7 @@ class ChildProcessWorker {
|
||||
error = response[4];
|
||||
|
||||
if (error != null && typeof error === 'object') {
|
||||
const extra = error; // @ts-ignore: no index
|
||||
const extra = error; // @ts-expect-error: no index
|
||||
|
||||
const NativeCtor = global[response[1]];
|
||||
const Ctor = typeof NativeCtor === 'function' ? NativeCtor : Error;
|
||||
@@ -235,7 +238,6 @@ class ChildProcessWorker {
|
||||
error.stack = response[3];
|
||||
|
||||
for (const key in extra) {
|
||||
// @ts-ignore: adding custom properties to errors.
|
||||
error[key] = extra[key];
|
||||
}
|
||||
}
|
||||
@@ -245,8 +247,7 @@ class ChildProcessWorker {
|
||||
break;
|
||||
|
||||
case _types().PARENT_MESSAGE_SETUP_ERROR:
|
||||
error = new Error('Error when calling setup: ' + response[2]); // @ts-ignore: adding custom properties to errors.
|
||||
|
||||
error = new Error('Error when calling setup: ' + response[2]);
|
||||
error.type = response[1];
|
||||
error.stack = response[3];
|
||||
|
||||
@@ -254,6 +255,11 @@ class ChildProcessWorker {
|
||||
|
||||
break;
|
||||
|
||||
case _types().PARENT_MESSAGE_CUSTOM:
|
||||
this._onCustomMessage(response[1]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new TypeError('Unexpected response from worker: ' + response[0]);
|
||||
}
|
||||
@@ -275,7 +281,7 @@ class ChildProcessWorker {
|
||||
}
|
||||
}
|
||||
|
||||
send(request, onProcessStart, onProcessEnd) {
|
||||
send(request, onProcessStart, onProcessEnd, onCustomMessage) {
|
||||
onProcessStart(this);
|
||||
|
||||
this._onProcessEnd = (...args) => {
|
||||
@@ -285,6 +291,8 @@ class ChildProcessWorker {
|
||||
return onProcessEnd(...args);
|
||||
};
|
||||
|
||||
this._onCustomMessage = (...arg) => onCustomMessage(...arg);
|
||||
|
||||
this._request = request;
|
||||
this._retries = 0;
|
||||
|
||||
|
||||
+3
-2
@@ -5,13 +5,14 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/// <reference types="node" />
|
||||
import { ChildMessage, OnEnd, OnStart, WorkerInterface, WorkerOptions } from '../types';
|
||||
import { ChildMessage, OnCustomMessage, OnEnd, OnStart, WorkerInterface, WorkerOptions } from '../types';
|
||||
export default class ExperimentalWorker implements WorkerInterface {
|
||||
private _worker;
|
||||
private _options;
|
||||
private _request;
|
||||
private _retries;
|
||||
private _onProcessEnd;
|
||||
private _onCustomMessage;
|
||||
private _fakeStream;
|
||||
private _stdout;
|
||||
private _stderr;
|
||||
@@ -25,7 +26,7 @@ export default class ExperimentalWorker implements WorkerInterface {
|
||||
private _onExit;
|
||||
waitForExit(): Promise<void>;
|
||||
forceExit(): void;
|
||||
send(request: ChildMessage, onProcessStart: OnStart, onProcessEnd: OnEnd): void;
|
||||
send(request: ChildMessage, onProcessStart: OnStart, onProcessEnd: OnEnd, onCustomMessage: OnCustomMessage): void;
|
||||
getWorkerId(): number;
|
||||
getStdout(): NodeJS.ReadableStream | null;
|
||||
getStderr(): NodeJS.ReadableStream | null;
|
||||
|
||||
+15
-4
@@ -127,6 +127,8 @@ class ExperimentalWorker {
|
||||
|
||||
_defineProperty(this, '_onProcessEnd', void 0);
|
||||
|
||||
_defineProperty(this, '_onCustomMessage', void 0);
|
||||
|
||||
_defineProperty(this, '_fakeStream', void 0);
|
||||
|
||||
_defineProperty(this, '_stdout', void 0);
|
||||
@@ -156,6 +158,8 @@ class ExperimentalWorker {
|
||||
path().resolve(__dirname, './threadChild.js'),
|
||||
{
|
||||
eval: false,
|
||||
// @ts-expect-error: added in newer versions
|
||||
resourceLimits: this._options.resourceLimits,
|
||||
stderr: true,
|
||||
stdout: true,
|
||||
workerData: {
|
||||
@@ -246,7 +250,7 @@ class ExperimentalWorker {
|
||||
error = response[4];
|
||||
|
||||
if (error != null && typeof error === 'object') {
|
||||
const extra = error; // @ts-ignore: no index
|
||||
const extra = error; // @ts-expect-error: no index
|
||||
|
||||
const NativeCtor = global[response[1]];
|
||||
const Ctor = typeof NativeCtor === 'function' ? NativeCtor : Error;
|
||||
@@ -255,7 +259,7 @@ class ExperimentalWorker {
|
||||
error.stack = response[3];
|
||||
|
||||
for (const key in extra) {
|
||||
// @ts-ignore: no index
|
||||
// @ts-expect-error: no index
|
||||
error[key] = extra[key];
|
||||
}
|
||||
}
|
||||
@@ -265,7 +269,7 @@ class ExperimentalWorker {
|
||||
break;
|
||||
|
||||
case _types().PARENT_MESSAGE_SETUP_ERROR:
|
||||
error = new Error('Error when calling setup: ' + response[2]); // @ts-ignore: adding custom properties to errors.
|
||||
error = new Error('Error when calling setup: ' + response[2]); // @ts-expect-error: adding custom properties to errors.
|
||||
|
||||
error.type = response[1];
|
||||
error.stack = response[3];
|
||||
@@ -274,6 +278,11 @@ class ExperimentalWorker {
|
||||
|
||||
break;
|
||||
|
||||
case _types().PARENT_MESSAGE_CUSTOM:
|
||||
this._onCustomMessage(response[1]);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new TypeError('Unexpected response from worker: ' + response[0]);
|
||||
}
|
||||
@@ -301,7 +310,7 @@ class ExperimentalWorker {
|
||||
this._worker.terminate();
|
||||
}
|
||||
|
||||
send(request, onProcessStart, onProcessEnd) {
|
||||
send(request, onProcessStart, onProcessEnd, onCustomMessage) {
|
||||
onProcessStart(this);
|
||||
|
||||
this._onProcessEnd = (...args) => {
|
||||
@@ -311,6 +320,8 @@ class ExperimentalWorker {
|
||||
return onProcessEnd(...args);
|
||||
};
|
||||
|
||||
this._onCustomMessage = (...arg) => onCustomMessage(...arg);
|
||||
|
||||
this._request = request;
|
||||
this._retries = 0;
|
||||
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
/// <reference types="node" />
|
||||
declare const messageParent: (message: unknown, parentProcess?: NodeJS.Process) => void;
|
||||
export default messageParent;
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
function _types() {
|
||||
const data = require('../types');
|
||||
|
||||
_types = function () {
|
||||
return data;
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
const isWorkerThread = () => {
|
||||
try {
|
||||
// `Require` here to support Node v10
|
||||
const {isMainThread, parentPort} = require('worker_threads');
|
||||
|
||||
return !isMainThread && parentPort;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const messageParent = (message, parentProcess = process) => {
|
||||
try {
|
||||
if (isWorkerThread()) {
|
||||
// `Require` here to support Node v10
|
||||
const {parentPort} = require('worker_threads');
|
||||
|
||||
parentPort.postMessage([_types().PARENT_MESSAGE_CUSTOM, message]);
|
||||
} else if (typeof parentProcess.send === 'function') {
|
||||
parentProcess.send([_types().PARENT_MESSAGE_CUSTOM, message]);
|
||||
}
|
||||
} catch {
|
||||
throw new Error('"messageParent" can only be used inside a worker');
|
||||
}
|
||||
};
|
||||
|
||||
var _default = messageParent;
|
||||
exports.default = _default;
|
||||
+6
-1
@@ -133,6 +133,11 @@ function execMethod(method, args) {
|
||||
execFunction(main.setup, main, setupArgs, execHelper, reportInitializeError);
|
||||
}
|
||||
|
||||
const isPromise = obj =>
|
||||
!!obj &&
|
||||
(typeof obj === 'object' || typeof obj === 'function') &&
|
||||
typeof obj.then === 'function';
|
||||
|
||||
function execFunction(fn, ctx, args, onResult, onError) {
|
||||
let result;
|
||||
|
||||
@@ -143,7 +148,7 @@ function execFunction(fn, ctx, args, onResult, onError) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result && typeof result.then === 'function') {
|
||||
if (isPromise(result)) {
|
||||
result.then(onResult, onError);
|
||||
} else {
|
||||
onResult(result);
|
||||
|
||||
+6
-1
@@ -146,6 +146,11 @@ function execMethod(method, args) {
|
||||
execFunction(main.setup, main, setupArgs, execHelper, reportInitializeError);
|
||||
}
|
||||
|
||||
const isPromise = obj =>
|
||||
!!obj &&
|
||||
(typeof obj === 'object' || typeof obj === 'function') &&
|
||||
typeof obj.then === 'function';
|
||||
|
||||
function execFunction(fn, ctx, args, onResult, onError) {
|
||||
let result;
|
||||
|
||||
@@ -156,7 +161,7 @@ function execFunction(fn, ctx, args, onResult, onError) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result && typeof result.then === 'function') {
|
||||
if (isPromise(result)) {
|
||||
result.then(onResult, onError);
|
||||
} else {
|
||||
onResult(result);
|
||||
|
||||
Reference in New Issue
Block a user