@atlaspack/workers 2.12.1-canary.3354
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/index.d.ts +23 -0
- package/lib/Handle.js +45 -0
- package/lib/Worker.js +188 -0
- package/lib/WorkerFarm.js +563 -0
- package/lib/backend.js +34 -0
- package/lib/bus.js +31 -0
- package/lib/child.js +294 -0
- package/lib/childState.js +14 -0
- package/lib/core-worker.browser.js +4 -0
- package/lib/core-worker.js +4 -0
- package/lib/cpuCount.js +79 -0
- package/lib/index.js +75 -0
- package/lib/process/ProcessChild.js +58 -0
- package/lib/process/ProcessWorker.js +83 -0
- package/lib/threads/ThreadsChild.js +49 -0
- package/lib/threads/ThreadsWorker.js +61 -0
- package/lib/types.js +1 -0
- package/lib/web/WebChild.js +44 -0
- package/lib/web/WebWorker.js +85 -0
- package/package.json +36 -0
- package/src/Handle.js +48 -0
- package/src/Worker.js +227 -0
- package/src/WorkerFarm.js +707 -0
- package/src/backend.js +33 -0
- package/src/bus.js +26 -0
- package/src/child.js +322 -0
- package/src/childState.js +10 -0
- package/src/core-worker.browser.js +3 -0
- package/src/core-worker.js +2 -0
- package/src/cpuCount.js +75 -0
- package/src/index.js +43 -0
- package/src/process/ProcessChild.js +56 -0
- package/src/process/ProcessWorker.js +91 -0
- package/src/threads/ThreadsChild.js +42 -0
- package/src/threads/ThreadsWorker.js +66 -0
- package/src/types.js +68 -0
- package/src/web/WebChild.js +53 -0
- package/src/web/WebWorker.js +88 -0
- package/test/cpuCount.test.js +19 -0
- package/test/integration/workerfarm/console.js +15 -0
- package/test/integration/workerfarm/echo.js +5 -0
- package/test/integration/workerfarm/ipc-pid.js +18 -0
- package/test/integration/workerfarm/ipc.js +10 -0
- package/test/integration/workerfarm/logging.js +19 -0
- package/test/integration/workerfarm/master-process-id.js +3 -0
- package/test/integration/workerfarm/master-sum.js +3 -0
- package/test/integration/workerfarm/ping.js +5 -0
- package/test/integration/workerfarm/resolve-shared-reference.js +5 -0
- package/test/integration/workerfarm/reverse-handle.js +5 -0
- package/test/integration/workerfarm/shared-reference.js +6 -0
- package/test/workerfarm.js +362 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import Logger from '@atlaspack/logger';
|
|
2
|
+
import assert from 'assert';
|
|
3
|
+
import WorkerFarm from '../src';
|
|
4
|
+
|
|
5
|
+
describe('WorkerFarm', function () {
|
|
6
|
+
this.timeout(30000);
|
|
7
|
+
|
|
8
|
+
it('Should start up workers', async () => {
|
|
9
|
+
let workerfarm = new WorkerFarm({
|
|
10
|
+
warmWorkers: false,
|
|
11
|
+
useLocalWorker: false,
|
|
12
|
+
workerPath: require.resolve('./integration/workerfarm/ping.js'),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
assert.equal(await workerfarm.run(), 'pong');
|
|
16
|
+
|
|
17
|
+
await workerfarm.end();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('Should handle 1000 requests without any issue', async () => {
|
|
21
|
+
let workerfarm = new WorkerFarm({
|
|
22
|
+
warmWorkers: false,
|
|
23
|
+
useLocalWorker: false,
|
|
24
|
+
workerPath: require.resolve('./integration/workerfarm/echo.js'),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
let promises = [];
|
|
28
|
+
for (let i = 0; i < 1000; i++) {
|
|
29
|
+
promises.push(workerfarm.run(i));
|
|
30
|
+
}
|
|
31
|
+
await Promise.all(promises);
|
|
32
|
+
|
|
33
|
+
await workerfarm.end();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('Should warm up workers', async () => {
|
|
37
|
+
let workerfarm = new WorkerFarm({
|
|
38
|
+
warmWorkers: true,
|
|
39
|
+
useLocalWorker: true,
|
|
40
|
+
workerPath: require.resolve('./integration/workerfarm/echo.js'),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < 100; i++) {
|
|
44
|
+
assert.equal(await workerfarm.run(i), i);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
await new Promise(resolve => workerfarm.once('warmedup', resolve));
|
|
48
|
+
|
|
49
|
+
assert(workerfarm.workers.size > 0, 'Should have spawned workers.');
|
|
50
|
+
assert(
|
|
51
|
+
workerfarm.warmWorkers >= workerfarm.workers.size,
|
|
52
|
+
'Should have warmed up workers.',
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
await workerfarm.end();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('Should use the local worker', async () => {
|
|
59
|
+
let workerfarm = new WorkerFarm({
|
|
60
|
+
warmWorkers: true,
|
|
61
|
+
useLocalWorker: true,
|
|
62
|
+
workerPath: require.resolve('./integration/workerfarm/echo.js'),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
assert.equal(await workerfarm.run('hello world'), 'hello world');
|
|
66
|
+
assert.equal(workerfarm.shouldUseRemoteWorkers(), false);
|
|
67
|
+
|
|
68
|
+
await workerfarm.end();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('Should be able to use bi-directional communication', async () => {
|
|
72
|
+
let workerfarm = new WorkerFarm({
|
|
73
|
+
warmWorkers: false,
|
|
74
|
+
useLocalWorker: false,
|
|
75
|
+
workerPath: require.resolve('./integration/workerfarm/ipc.js'),
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
assert.equal(await workerfarm.run(1, 2), 3);
|
|
79
|
+
|
|
80
|
+
await workerfarm.end();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('Should be able to handle 1000 bi-directional calls', async () => {
|
|
84
|
+
let workerfarm = new WorkerFarm({
|
|
85
|
+
warmWorkers: false,
|
|
86
|
+
useLocalWorker: false,
|
|
87
|
+
workerPath: require.resolve('./integration/workerfarm/ipc.js'),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < 1000; i++) {
|
|
91
|
+
assert.equal(await workerfarm.run(1 + i, 2), 3 + i);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
await workerfarm.end();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it.skip('Bi-directional call should return masters pid', async () => {
|
|
98
|
+
// TODO: this test is only good for processes not threads
|
|
99
|
+
let workerfarm = new WorkerFarm({
|
|
100
|
+
warmWorkers: false,
|
|
101
|
+
useLocalWorker: false,
|
|
102
|
+
workerPath: require.resolve('./integration/workerfarm/ipc-pid.js'),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
let result = await workerfarm.run();
|
|
106
|
+
assert.equal(result.length, 2);
|
|
107
|
+
assert.equal(result[1], process.pid);
|
|
108
|
+
assert.notEqual(result[0], process.pid);
|
|
109
|
+
|
|
110
|
+
await workerfarm.end();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('Should handle 10 big concurrent requests without any issue', async () => {
|
|
114
|
+
// This emulates the node.js ipc bug for win32
|
|
115
|
+
let workerfarm = new WorkerFarm({
|
|
116
|
+
warmWorkers: false,
|
|
117
|
+
useLocalWorker: false,
|
|
118
|
+
workerPath: require.resolve('./integration/workerfarm/echo.js'),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
let bigData = [];
|
|
122
|
+
for (let i = 0; i < 10000; i++) {
|
|
123
|
+
bigData.push('This is some big data');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let promises = [];
|
|
127
|
+
for (let i = 0; i < 10; i++) {
|
|
128
|
+
promises.push(workerfarm.run(bigData));
|
|
129
|
+
}
|
|
130
|
+
await Promise.all(promises);
|
|
131
|
+
|
|
132
|
+
await workerfarm.end();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('Forwards stdio from the child process and levels event source if shouldPatchConsole is true', async () => {
|
|
136
|
+
let events = [];
|
|
137
|
+
let logDisposable = Logger.onLog(event => events.push(event));
|
|
138
|
+
|
|
139
|
+
let workerfarm = new WorkerFarm({
|
|
140
|
+
warmWorkers: true,
|
|
141
|
+
useLocalWorker: false,
|
|
142
|
+
workerPath: require.resolve('./integration/workerfarm/console.js'),
|
|
143
|
+
shouldPatchConsole: true,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await workerfarm.run();
|
|
147
|
+
|
|
148
|
+
assert.deepEqual(events, [
|
|
149
|
+
{
|
|
150
|
+
level: 'info',
|
|
151
|
+
type: 'log',
|
|
152
|
+
diagnostics: [
|
|
153
|
+
{
|
|
154
|
+
origin: 'console',
|
|
155
|
+
message: 'one',
|
|
156
|
+
skipFormatting: true,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
level: 'info',
|
|
162
|
+
type: 'log',
|
|
163
|
+
diagnostics: [
|
|
164
|
+
{
|
|
165
|
+
origin: 'console',
|
|
166
|
+
message: 'two',
|
|
167
|
+
skipFormatting: true,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
level: 'warn',
|
|
173
|
+
type: 'log',
|
|
174
|
+
diagnostics: [
|
|
175
|
+
{
|
|
176
|
+
origin: 'console',
|
|
177
|
+
message: 'three',
|
|
178
|
+
skipFormatting: true,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
level: 'error',
|
|
184
|
+
type: 'log',
|
|
185
|
+
diagnostics: [
|
|
186
|
+
{
|
|
187
|
+
origin: 'console',
|
|
188
|
+
message: 'four',
|
|
189
|
+
skipFormatting: true,
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
level: 'verbose',
|
|
195
|
+
type: 'log',
|
|
196
|
+
diagnostics: [
|
|
197
|
+
{
|
|
198
|
+
message: 'five',
|
|
199
|
+
origin: 'console',
|
|
200
|
+
skipFormatting: true,
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
},
|
|
204
|
+
]);
|
|
205
|
+
|
|
206
|
+
logDisposable.dispose();
|
|
207
|
+
await workerfarm.end();
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('Forwards logger events to the main process', async () => {
|
|
211
|
+
let events = [];
|
|
212
|
+
let logDisposable = Logger.onLog(event => events.push(event));
|
|
213
|
+
|
|
214
|
+
let workerfarm = new WorkerFarm({
|
|
215
|
+
warmWorkers: true,
|
|
216
|
+
useLocalWorker: false,
|
|
217
|
+
workerPath: require.resolve('./integration/workerfarm/logging.js'),
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
await workerfarm.run();
|
|
221
|
+
|
|
222
|
+
// assert.equal(events.length, 2);
|
|
223
|
+
assert.deepEqual(events, [
|
|
224
|
+
{
|
|
225
|
+
level: 'info',
|
|
226
|
+
diagnostics: [
|
|
227
|
+
{
|
|
228
|
+
origin: 'logging-worker',
|
|
229
|
+
message: 'omg it works',
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
type: 'log',
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
level: 'error',
|
|
236
|
+
diagnostics: [
|
|
237
|
+
{
|
|
238
|
+
origin: 'logging-worker',
|
|
239
|
+
message: 'errors objects dont work yet',
|
|
240
|
+
},
|
|
241
|
+
],
|
|
242
|
+
type: 'log',
|
|
243
|
+
},
|
|
244
|
+
]);
|
|
245
|
+
|
|
246
|
+
logDisposable.dispose();
|
|
247
|
+
await workerfarm.end();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('Should support reverse handle functions in main process that can be called in workers', async () => {
|
|
251
|
+
let workerfarm = new WorkerFarm({
|
|
252
|
+
warmWorkers: true,
|
|
253
|
+
useLocalWorker: false,
|
|
254
|
+
workerPath: require.resolve('./integration/workerfarm/reverse-handle.js'),
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
let handle = workerfarm.createReverseHandle(() => 42);
|
|
258
|
+
let result = await workerfarm.run(handle);
|
|
259
|
+
assert.equal(result, 42);
|
|
260
|
+
await workerfarm.end();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('Should dispose of handle objects when ending', async () => {
|
|
264
|
+
let workerfarm = new WorkerFarm({
|
|
265
|
+
warmWorkers: true,
|
|
266
|
+
useLocalWorker: false,
|
|
267
|
+
workerPath: require.resolve('./integration/workerfarm/reverse-handle.js'),
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
workerfarm.createReverseHandle(() => 42);
|
|
271
|
+
assert.equal(workerfarm.handles.size, 1);
|
|
272
|
+
await workerfarm.end();
|
|
273
|
+
assert.equal(workerfarm.handles.size, 0);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it('Should support shared references in workers', async () => {
|
|
277
|
+
let workerfarm = new WorkerFarm({
|
|
278
|
+
warmWorkers: true,
|
|
279
|
+
useLocalWorker: false,
|
|
280
|
+
workerPath: require.resolve(
|
|
281
|
+
'./integration/workerfarm/shared-reference.js',
|
|
282
|
+
),
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
let sharedValue = 'Something to be shared';
|
|
286
|
+
let {ref, dispose} = await workerfarm.createSharedReference(sharedValue);
|
|
287
|
+
let result = await workerfarm.run(ref);
|
|
288
|
+
assert.equal(result, 'Something to be shared');
|
|
289
|
+
await dispose();
|
|
290
|
+
result = await workerfarm.run(ref);
|
|
291
|
+
assert.equal(result, 'Shared reference does not exist');
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it('Should resolve shared references in workers', async () => {
|
|
295
|
+
let workerfarm = new WorkerFarm({
|
|
296
|
+
warmWorkers: true,
|
|
297
|
+
useLocalWorker: false,
|
|
298
|
+
workerPath: require.resolve(
|
|
299
|
+
'./integration/workerfarm/resolve-shared-reference.js',
|
|
300
|
+
),
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
let sharedValue = 'Something to be shared';
|
|
304
|
+
let {ref, dispose} = await workerfarm.createSharedReference(sharedValue);
|
|
305
|
+
|
|
306
|
+
assert.equal(workerfarm.workerApi.resolveSharedReference(sharedValue), ref);
|
|
307
|
+
assert.ok(await workerfarm.run(ref));
|
|
308
|
+
|
|
309
|
+
await dispose();
|
|
310
|
+
assert(workerfarm.workerApi.resolveSharedReference(sharedValue) == null);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('Should support shared references in local worker', async () => {
|
|
314
|
+
let workerfarm = new WorkerFarm({
|
|
315
|
+
warmWorkers: true,
|
|
316
|
+
useLocalWorker: true,
|
|
317
|
+
workerPath: require.resolve(
|
|
318
|
+
'./integration/workerfarm/shared-reference.js',
|
|
319
|
+
),
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
let sharedValue = 'Something to be shared';
|
|
323
|
+
let {ref, dispose} = await workerfarm.createSharedReference(sharedValue);
|
|
324
|
+
let result = await workerfarm.run(ref);
|
|
325
|
+
assert.equal(result, 'Something to be shared');
|
|
326
|
+
await dispose();
|
|
327
|
+
result = await workerfarm.run(ref);
|
|
328
|
+
assert.equal(result, 'Shared reference does not exist');
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it('should resolve shared references in local worker', async () => {
|
|
332
|
+
let workerfarm = new WorkerFarm({
|
|
333
|
+
warmWorkers: true,
|
|
334
|
+
useLocalWorker: true,
|
|
335
|
+
workerPath: require.resolve(
|
|
336
|
+
'./integration/workerfarm/resolve-shared-reference.js',
|
|
337
|
+
),
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
let sharedValue = 'Something to be shared';
|
|
341
|
+
let {ref, dispose} = await workerfarm.createSharedReference(sharedValue);
|
|
342
|
+
|
|
343
|
+
assert.equal(workerfarm.workerApi.resolveSharedReference(sharedValue), ref);
|
|
344
|
+
assert.ok(await workerfarm.run(ref));
|
|
345
|
+
|
|
346
|
+
await dispose();
|
|
347
|
+
assert(workerfarm.workerApi.resolveSharedReference(sharedValue) == null);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
it('Should dispose of shared references when ending', async () => {
|
|
351
|
+
let workerfarm = new WorkerFarm({
|
|
352
|
+
warmWorkers: true,
|
|
353
|
+
useLocalWorker: false,
|
|
354
|
+
workerPath: require.resolve('./integration/workerfarm/reverse-handle.js'),
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
workerfarm.createSharedReference('Something to be shared');
|
|
358
|
+
assert.equal(workerfarm.sharedReferences.size, 1);
|
|
359
|
+
await workerfarm.end();
|
|
360
|
+
assert.equal(workerfarm.sharedReferences.size, 0);
|
|
361
|
+
});
|
|
362
|
+
});
|