This repository was archived by the owner on Dec 5, 2019. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 179
/
Copy pathTaskRunner.js
110 lines (98 loc) · 2.74 KB
/
TaskRunner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import os from 'os';
import cacache from 'cacache';
import findCacheDir from 'find-cache-dir';
import workerFarm from 'worker-farm';
import serialize from 'serialize-javascript';
import isWsl from 'is-wsl';
import minify from './minify';
const workerFile = require.resolve('./worker');
export default class TaskRunner {
constructor(options = {}) {
const { cache, parallel } = options;
this.cacheDir =
cache === true
? findCacheDir({ name: 'uglifyjs-webpack-plugin' }) || os.tmpdir()
: cache;
// In some cases cpus() returns undefined
// https://github.com/nodejs/node/issues/19022
const cpus = os.cpus() || { length: 1 };
this.maxConcurrentWorkers = isWsl
? 1
: parallel === true
? cpus.length - 1
: Math.min(Number(parallel) || 0, cpus.length - 1);
}
run(tasks, callback) {
/* istanbul ignore if */
if (!tasks.length) {
callback(null, []);
return;
}
if (this.maxConcurrentWorkers > 1) {
const workerOptions =
process.platform === 'win32'
? {
maxConcurrentWorkers: this.maxConcurrentWorkers,
maxConcurrentCallsPerWorker: 1,
}
: { maxConcurrentWorkers: this.maxConcurrentWorkers };
this.workers = workerFarm(workerOptions, workerFile);
this.boundWorkers = (options, cb) => {
try {
this.workers(serialize(options), cb);
} catch (error) {
// worker-farm can fail with ENOMEM or something else
cb(error);
}
};
} else {
this.boundWorkers = (options, cb) => {
try {
cb(null, minify(options));
} catch (error) {
cb(error);
}
};
}
let toRun = tasks.length;
const results = [];
const step = (index, data) => {
toRun -= 1;
results[index] = data;
if (!toRun) {
callback(null, results);
}
};
tasks.forEach((task, index) => {
const enqueue = () => {
this.boundWorkers(task, (error, data) => {
const result = error ? { error } : data;
const done = () => step(index, result);
if (this.cacheDir && !result.error) {
cacache
.put(
this.cacheDir,
serialize(task.cacheKeys),
JSON.stringify(data)
)
.then(done, done);
} else {
done();
}
});
};
if (this.cacheDir) {
cacache
.get(this.cacheDir, serialize(task.cacheKeys))
.then(({ data }) => step(index, JSON.parse(data)), enqueue);
} else {
enqueue();
}
});
}
exit() {
if (this.workers) {
workerFarm.end(this.workers);
}
}
}