multi-tasks 3.0.3 → 3.0.4
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/README.md +7 -2
- package/package.json +1 -1
- package/utils/resolveWorkers.js +31 -0
- package/workers/Multithread.js +2 -0
- package/workers/asMaster.js +2 -2
package/README.md
CHANGED
|
@@ -23,9 +23,9 @@ npm install multi-tasks
|
|
|
23
23
|
- `taskRootFolder` — root directory where progress and result files are stored.
|
|
24
24
|
- `taskId` — task folder name under `taskRootFolder`.
|
|
25
25
|
- `taskFolder` — full task folder path, required by `restart`.
|
|
26
|
-
- `numberOfWorkers` — how many worker processes run in parallel.
|
|
26
|
+
- `numberOfWorkers` — how many worker processes run in parallel; also accepts a percentage string of CPU cores, e.g. `"50%"`.
|
|
27
27
|
- `taskTimeout` — optional, milliseconds; an overdue task fails with a timeout error.
|
|
28
|
-
- `maxTaskRetries` — optional, max times a failed task is auto-retried
|
|
28
|
+
- `maxTaskRetries` — optional, max times a failed task is auto-retried.
|
|
29
29
|
- `autoCloseAfterCompletion` — set `false` if you create new tasks dynamically.
|
|
30
30
|
- `shouldTerminate(info)` — return `true` to terminate the whole process.
|
|
31
31
|
- `onFinish(report)` — called once after all workers are done.
|
|
@@ -161,6 +161,7 @@ The usage patterns documented above are covered by automated tests (unit tests i
|
|
|
161
161
|
|
|
162
162
|
### Changelog:
|
|
163
163
|
|
|
164
|
+
- 3.0.4 numberOfWorkers accepts a percentage string of CPU cores, e.g. "50%"
|
|
164
165
|
- 3.0.3 Support 'maxTaskRetries'
|
|
165
166
|
- 3.0.2 Support 'taskTimeout'
|
|
166
167
|
- 3.0.1 Versions 3.0.0 and above are maintained by AI
|
|
@@ -199,3 +200,7 @@ The usage patterns documented above are covered by automated tests (unit tests i
|
|
|
199
200
|
### Gitee:
|
|
200
201
|
|
|
201
202
|
[https://gitee.com/zhanglei923/multi-tasks](https://gitee.com/zhanglei923/multi-tasks)
|
|
203
|
+
|
|
204
|
+
### License:
|
|
205
|
+
|
|
206
|
+
[MIT](https://opensource.org/licenses/MIT) (see [LICENSE](LICENSE))
|
package/package.json
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const numCPUs = require('os').cpus().length;
|
|
4
|
+
|
|
5
|
+
const PERCENT_PATTERN = /^(\d+(?:\.\d+)?)%$/;
|
|
6
|
+
|
|
7
|
+
// 解析 numberOfWorkers 配置:
|
|
8
|
+
// - undefined -> CPU 核数减 1(默认);
|
|
9
|
+
// - number -> 原样返回(现状行为不变);
|
|
10
|
+
// - string -> 必须是 "数字%" 形式且百分比在 1-100 之间, 按核数四舍五入折算, 最小为 1;
|
|
11
|
+
// - 其余 -> 抛 Error。
|
|
12
|
+
const resolveNumberOfWorkers = (value) => {
|
|
13
|
+
if (typeof value === 'undefined') {
|
|
14
|
+
return numCPUs - 1;
|
|
15
|
+
};
|
|
16
|
+
if (typeof value === 'number') {
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
if (typeof value === 'string') {
|
|
20
|
+
const match = value.trim().match(PERCENT_PATTERN);
|
|
21
|
+
if (match) {
|
|
22
|
+
const percent = parseFloat(match[1]);
|
|
23
|
+
if (percent >= 1 && percent <= 100) {
|
|
24
|
+
return Math.max(1, Math.round(numCPUs * percent / 100));
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
throw new Error(`Invalid numberOfWorkers: ${JSON.stringify(value)}. Expected a number or a percentage string like "50%" (1-100).`);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
module.exports = { resolveNumberOfWorkers };
|
package/workers/Multithread.js
CHANGED
|
@@ -8,6 +8,7 @@ const asMaster = require('./asMaster');
|
|
|
8
8
|
const TaskMgr = require('./TaskMgr');
|
|
9
9
|
const WorkerMgr = require('./WorkerMgr');
|
|
10
10
|
const helper = require('./helper');
|
|
11
|
+
const { resolveNumberOfWorkers } = require('../utils/resolveWorkers');
|
|
11
12
|
|
|
12
13
|
let fmtdigit = (n)=>{
|
|
13
14
|
return n > 9 ? "" + n: "0" + n;
|
|
@@ -50,6 +51,7 @@ const start = (config)=>{
|
|
|
50
51
|
if (isMaster) {//init
|
|
51
52
|
console.log('[Master]: Start!!');
|
|
52
53
|
let PID = process.pid;
|
|
54
|
+
config.numberOfWorkers = resolveNumberOfWorkers(config.numberOfWorkers);//支持百分比字符串; 须在 fork 循环读值前折算, 非法值在此抛错
|
|
53
55
|
let numOfWorkers = config.numberOfWorkers;
|
|
54
56
|
console.log(` numCPUs=${numCPUs}`);
|
|
55
57
|
console.log(` numOfWorkers=${numOfWorkers}`);
|
package/workers/asMaster.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
var fs = require('fs');
|
|
2
2
|
var pathUtil = require('path');
|
|
3
|
-
const numCPUs = require('os').cpus().length;
|
|
4
3
|
|
|
5
4
|
const TaskMgr = require('./TaskMgr');
|
|
6
5
|
const randomsUtil = require('../utils/randoms');
|
|
6
|
+
const { resolveNumberOfWorkers } = require('../utils/resolveWorkers');
|
|
7
7
|
|
|
8
8
|
const resume = (config)=>{
|
|
9
9
|
config.__resume = true;
|
|
@@ -60,7 +60,7 @@ const init = (config)=>{
|
|
|
60
60
|
if(!config.initialTasks){ throw new Error('Please provide initialTasks data!'); };
|
|
61
61
|
if(!config.processTask){ throw new Error('Please provide processTask function!'); };
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
config.numberOfWorkers = resolveNumberOfWorkers(config.numberOfWorkers);//支持百分比字符串, 非法值在此抛错(fail fast, 不建任务目录)
|
|
64
64
|
|
|
65
65
|
let {taskRootFolder, taskName} = config;
|
|
66
66
|
|