aboutsummaryrefslogtreecommitdiff
path: root/node_modules/jest-worker/build/Farm.js
diff options
context:
space:
mode:
authorJoel Kronqvist <work.joelkronqvist@pm.me>2022-03-11 20:46:06 +0200
committerJoel Kronqvist <work.joelkronqvist@pm.me>2022-03-11 20:46:06 +0200
commit080c5819d87b933816d724a83f3bf4f1686770a7 (patch)
tree4a2ccc68b27edf7d4cbc586c932cc7542b655e19 /node_modules/jest-worker/build/Farm.js
parent5ac7049a9d30733165cc212dee308163c2a14644 (diff)
parentd003b82235a9329f912522a2f70aa950dfce4998 (diff)
downloadLYLLRuoka-080c5819d87b933816d724a83f3bf4f1686770a7.tar.gz
LYLLRuoka-080c5819d87b933816d724a83f3bf4f1686770a7.zip
Merge branch 'master' of https://github.com/JoelHMikael/FoodJS
Updating remote changes
Diffstat (limited to 'node_modules/jest-worker/build/Farm.js')
-rw-r--r--node_modules/jest-worker/build/Farm.js206
1 files changed, 206 insertions, 0 deletions
diff --git a/node_modules/jest-worker/build/Farm.js b/node_modules/jest-worker/build/Farm.js
new file mode 100644
index 0000000..e29daf5
--- /dev/null
+++ b/node_modules/jest-worker/build/Farm.js
@@ -0,0 +1,206 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', {
+ value: true
+});
+exports.default = void 0;
+
+var _FifoQueue = _interopRequireDefault(require('./FifoQueue'));
+
+var _types = require('./types');
+
+function _interopRequireDefault(obj) {
+ return obj && obj.__esModule ? obj : {default: obj};
+}
+
+function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+ return obj;
+}
+
+class Farm {
+ constructor(_numOfWorkers, _callback, options = {}) {
+ var _options$workerSchedu, _options$taskQueue;
+
+ _defineProperty(this, '_computeWorkerKey', void 0);
+
+ _defineProperty(this, '_workerSchedulingPolicy', void 0);
+
+ _defineProperty(this, '_cacheKeys', Object.create(null));
+
+ _defineProperty(this, '_locks', []);
+
+ _defineProperty(this, '_offset', 0);
+
+ _defineProperty(this, '_taskQueue', void 0);
+
+ this._numOfWorkers = _numOfWorkers;
+ this._callback = _callback;
+ this._computeWorkerKey = options.computeWorkerKey;
+ this._workerSchedulingPolicy =
+ (_options$workerSchedu = options.workerSchedulingPolicy) !== null &&
+ _options$workerSchedu !== void 0
+ ? _options$workerSchedu
+ : 'round-robin';
+ this._taskQueue =
+ (_options$taskQueue = options.taskQueue) !== null &&
+ _options$taskQueue !== void 0
+ ? _options$taskQueue
+ : new _FifoQueue.default();
+ }
+
+ doWork(method, ...args) {
+ 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( // Bind args to this function so it won't reference to the parent scope.
+ // This prevents a memory leak in v8, because otherwise the function will
+ // retaine args for the closure.
+ ((args, resolve, reject) => {
+ const computeWorkerKey = this._computeWorkerKey;
+ const request = [_types.CHILD_MESSAGE_CALL, false, method, args];
+ let worker = null;
+ let hash = null;
+
+ if (computeWorkerKey) {
+ hash = computeWorkerKey.call(this, method, ...args);
+ worker = hash == null ? null : this._cacheKeys[hash];
+ }
+
+ const onStart = worker => {
+ if (hash != null) {
+ this._cacheKeys[hash] = worker;
+ }
+ };
+
+ const onEnd = (error, result) => {
+ customMessageListeners.clear();
+
+ if (error) {
+ reject(error);
+ } else {
+ resolve(result);
+ }
+ };
+
+ const task = {
+ onCustomMessage,
+ onEnd,
+ onStart,
+ request
+ };
+
+ if (worker) {
+ this._taskQueue.enqueue(task, worker.getWorkerId());
+
+ this._process(worker.getWorkerId());
+ } else {
+ this._push(task);
+ }
+ }).bind(null, args)
+ );
+ promise.UNSTABLE_onCustomMessage = addCustomMessageListener;
+ return promise;
+ }
+
+ _process(workerId) {
+ if (this._isLocked(workerId)) {
+ return this;
+ }
+
+ const task = this._taskQueue.dequeue(workerId);
+
+ if (!task) {
+ return this;
+ }
+
+ if (task.request[1]) {
+ throw new Error('Queue implementation returned processed task');
+ } // Reference the task object outside so it won't be retained by onEnd,
+ // and other properties of the task object, such as task.request can be
+ // garbage collected.
+
+ const taskOnEnd = task.onEnd;
+
+ const onEnd = (error, result) => {
+ taskOnEnd(error, result);
+
+ this._unlock(workerId);
+
+ this._process(workerId);
+ };
+
+ task.request[1] = true;
+
+ this._lock(workerId);
+
+ this._callback(
+ workerId,
+ task.request,
+ task.onStart,
+ onEnd,
+ task.onCustomMessage
+ );
+
+ return this;
+ }
+
+ _push(task) {
+ this._taskQueue.enqueue(task);
+
+ const offset = this._getNextWorkerOffset();
+
+ for (let i = 0; i < this._numOfWorkers; i++) {
+ this._process((offset + i) % this._numOfWorkers);
+
+ if (task.request[1]) {
+ break;
+ }
+ }
+
+ return this;
+ }
+
+ _getNextWorkerOffset() {
+ switch (this._workerSchedulingPolicy) {
+ case 'in-order':
+ return 0;
+
+ case 'round-robin':
+ return this._offset++;
+ }
+ }
+
+ _lock(workerId) {
+ this._locks[workerId] = true;
+ }
+
+ _unlock(workerId) {
+ this._locks[workerId] = false;
+ }
+
+ _isLocked(workerId) {
+ return this._locks[workerId];
+ }
+}
+
+exports.default = Farm;