source: imaps-frontend/node_modules/jest-worker/build/Farm.js

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 4.7 KB
Line 
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true
5});
6exports.default = void 0;
7
8var _FifoQueue = _interopRequireDefault(require('./FifoQueue'));
9
10var _types = require('./types');
11
12function _interopRequireDefault(obj) {
13 return obj && obj.__esModule ? obj : {default: obj};
14}
15
16function _defineProperty(obj, key, value) {
17 if (key in obj) {
18 Object.defineProperty(obj, key, {
19 value: value,
20 enumerable: true,
21 configurable: true,
22 writable: true
23 });
24 } else {
25 obj[key] = value;
26 }
27 return obj;
28}
29
30class Farm {
31 constructor(_numOfWorkers, _callback, options = {}) {
32 var _options$workerSchedu, _options$taskQueue;
33
34 _defineProperty(this, '_computeWorkerKey', void 0);
35
36 _defineProperty(this, '_workerSchedulingPolicy', void 0);
37
38 _defineProperty(this, '_cacheKeys', Object.create(null));
39
40 _defineProperty(this, '_locks', []);
41
42 _defineProperty(this, '_offset', 0);
43
44 _defineProperty(this, '_taskQueue', void 0);
45
46 this._numOfWorkers = _numOfWorkers;
47 this._callback = _callback;
48 this._computeWorkerKey = options.computeWorkerKey;
49 this._workerSchedulingPolicy =
50 (_options$workerSchedu = options.workerSchedulingPolicy) !== null &&
51 _options$workerSchedu !== void 0
52 ? _options$workerSchedu
53 : 'round-robin';
54 this._taskQueue =
55 (_options$taskQueue = options.taskQueue) !== null &&
56 _options$taskQueue !== void 0
57 ? _options$taskQueue
58 : new _FifoQueue.default();
59 }
60
61 doWork(method, ...args) {
62 const customMessageListeners = new Set();
63
64 const addCustomMessageListener = listener => {
65 customMessageListeners.add(listener);
66 return () => {
67 customMessageListeners.delete(listener);
68 };
69 };
70
71 const onCustomMessage = message => {
72 customMessageListeners.forEach(listener => listener(message));
73 };
74
75 const promise = new Promise( // Bind args to this function so it won't reference to the parent scope.
76 // This prevents a memory leak in v8, because otherwise the function will
77 // retaine args for the closure.
78 ((args, resolve, reject) => {
79 const computeWorkerKey = this._computeWorkerKey;
80 const request = [_types.CHILD_MESSAGE_CALL, false, method, args];
81 let worker = null;
82 let hash = null;
83
84 if (computeWorkerKey) {
85 hash = computeWorkerKey.call(this, method, ...args);
86 worker = hash == null ? null : this._cacheKeys[hash];
87 }
88
89 const onStart = worker => {
90 if (hash != null) {
91 this._cacheKeys[hash] = worker;
92 }
93 };
94
95 const onEnd = (error, result) => {
96 customMessageListeners.clear();
97
98 if (error) {
99 reject(error);
100 } else {
101 resolve(result);
102 }
103 };
104
105 const task = {
106 onCustomMessage,
107 onEnd,
108 onStart,
109 request
110 };
111
112 if (worker) {
113 this._taskQueue.enqueue(task, worker.getWorkerId());
114
115 this._process(worker.getWorkerId());
116 } else {
117 this._push(task);
118 }
119 }).bind(null, args)
120 );
121 promise.UNSTABLE_onCustomMessage = addCustomMessageListener;
122 return promise;
123 }
124
125 _process(workerId) {
126 if (this._isLocked(workerId)) {
127 return this;
128 }
129
130 const task = this._taskQueue.dequeue(workerId);
131
132 if (!task) {
133 return this;
134 }
135
136 if (task.request[1]) {
137 throw new Error('Queue implementation returned processed task');
138 } // Reference the task object outside so it won't be retained by onEnd,
139 // and other properties of the task object, such as task.request can be
140 // garbage collected.
141
142 const taskOnEnd = task.onEnd;
143
144 const onEnd = (error, result) => {
145 taskOnEnd(error, result);
146
147 this._unlock(workerId);
148
149 this._process(workerId);
150 };
151
152 task.request[1] = true;
153
154 this._lock(workerId);
155
156 this._callback(
157 workerId,
158 task.request,
159 task.onStart,
160 onEnd,
161 task.onCustomMessage
162 );
163
164 return this;
165 }
166
167 _push(task) {
168 this._taskQueue.enqueue(task);
169
170 const offset = this._getNextWorkerOffset();
171
172 for (let i = 0; i < this._numOfWorkers; i++) {
173 this._process((offset + i) % this._numOfWorkers);
174
175 if (task.request[1]) {
176 break;
177 }
178 }
179
180 return this;
181 }
182
183 _getNextWorkerOffset() {
184 switch (this._workerSchedulingPolicy) {
185 case 'in-order':
186 return 0;
187
188 case 'round-robin':
189 return this._offset++;
190 }
191 }
192
193 _lock(workerId) {
194 this._locks[workerId] = true;
195 }
196
197 _unlock(workerId) {
198 this._locks[workerId] = false;
199 }
200
201 _isLocked(workerId) {
202 return this._locks[workerId];
203 }
204}
205
206exports.default = Farm;
Note: See TracBrowser for help on using the repository browser.