multi-tasks 2.0.0 → 2.0.2
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 +4 -1
- package/examples/example0/run-readme.js +1 -1
- package/examples/example0/run.js +1 -1
- package/package.json +1 -1
- package/utils/asyncQueue.js +7 -3
- package/workers/Multithread.js +27 -4
- package/workers/TaskMgr.js +1 -1
- package/workers/index.js +36 -1
- package/examples/example3-dynamicIncreasing/RunnerConsumer.js +0 -176
- package/examples/example3-dynamicIncreasing/RunnerProducer.js +0 -49
- package/examples/example3-dynamicIncreasing/run.js +0 -36
- package/examples/example3-dynamicIncreasing/util.js +0 -46
package/README.md
CHANGED
|
@@ -90,13 +90,14 @@ let processTask = (task, helper)=>{
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
//Step3, run!
|
|
93
|
-
multiTasks({
|
|
93
|
+
multiTasks.start({
|
|
94
94
|
tasks: alltasks,
|
|
95
95
|
processTask,
|
|
96
96
|
taskRootFolder: `../examples-tmp-data/example0`, //a directory to store progress and results files, you can check the progress here
|
|
97
97
|
taskId: 'my-task',
|
|
98
98
|
numberOfWorkers: 3, //Assign how many workers are working in parallel
|
|
99
99
|
//autoCloseAfterCompletion: true, //if you have dynamically generated new tasks, put this as false
|
|
100
|
+
shouldTerminate,//return true if you need to terminate the whole process
|
|
100
101
|
onFinish: (report)=>{
|
|
101
102
|
console.log('finish callback', report);
|
|
102
103
|
}
|
|
@@ -113,6 +114,8 @@ node examples/example1/run
|
|
|
113
114
|
|
|
114
115
|
Changelog:
|
|
115
116
|
|
|
117
|
+
- 2.0.2 new feature: support shouldTerminate
|
|
118
|
+
- 2.0.1 Avoid possible I/O conflicts.
|
|
116
119
|
- 2.0.0 Rewritten with a new architecture to support dynamic tasks.
|
|
117
120
|
- 1.2.8 Fix: create task folder failed on MacOS
|
|
118
121
|
- 1.2.7 Small updates
|
|
@@ -75,7 +75,7 @@ let processTask = (task, helper)=>{
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
//Step3, run!
|
|
78
|
-
multiTasks({
|
|
78
|
+
multiTasks.start({
|
|
79
79
|
tasks: alltasks,
|
|
80
80
|
processTask,
|
|
81
81
|
taskRootFolder: `../examples-tmp-data/example0`, //a directory to store progress and results files, you can check the progress here
|
package/examples/example0/run.js
CHANGED
|
@@ -40,7 +40,7 @@ let processTask = (task, helper)=>{
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
//Step3, run!
|
|
43
|
-
multiTasks({
|
|
43
|
+
multiTasks.start({
|
|
44
44
|
tasks: alltasks,
|
|
45
45
|
processTask,
|
|
46
46
|
taskRootFolder: `../examples-tmp-data/example0`, //a directory to store progress and results files, you can check the progress here
|
package/package.json
CHANGED
package/utils/asyncQueue.js
CHANGED
|
@@ -18,14 +18,18 @@ class AsyncQueue {
|
|
|
18
18
|
}
|
|
19
19
|
const task = this.queue.shift();
|
|
20
20
|
let result = task();
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
let isPromise = result instanceof Promise;
|
|
22
|
+
//console.log('r=q',isPromise)
|
|
23
|
+
if(!isPromise) {
|
|
24
|
+
console.error('[ERR]Queue functions must return a promise object');
|
|
25
|
+
throw 'Queue functions must return a promise object';
|
|
26
|
+
}
|
|
23
27
|
try {
|
|
24
28
|
await result;
|
|
25
29
|
} catch (error) {
|
|
26
30
|
console.error('Error processing task:', error);
|
|
27
31
|
}
|
|
28
|
-
this.processNext();
|
|
32
|
+
this.processNext();
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
|
package/workers/Multithread.js
CHANGED
|
@@ -29,6 +29,21 @@ let USER_CONFIG;
|
|
|
29
29
|
|
|
30
30
|
let taskCount = 0;
|
|
31
31
|
|
|
32
|
+
let killAllWorkers = ()=>{
|
|
33
|
+
for (const id in cluster.workers) {
|
|
34
|
+
if (cluster.workers.hasOwnProperty(id)) {
|
|
35
|
+
const worker = cluster.workers[id];
|
|
36
|
+
console.log(`Killing worker ${worker.process.pid}`);
|
|
37
|
+
killWorker(worker);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
let killWorker = (worker)=>{
|
|
42
|
+
worker.disconnect();
|
|
43
|
+
//worker.process.kill();
|
|
44
|
+
worker.kill();
|
|
45
|
+
};
|
|
46
|
+
|
|
32
47
|
const start = (config)=>{
|
|
33
48
|
USER_CONFIG = config;//this will remain user defined functions
|
|
34
49
|
let isMaster = (cluster.isPrimary || cluster.isMaster);
|
|
@@ -53,15 +68,17 @@ const start = (config)=>{
|
|
|
53
68
|
WorkerMgr.addWorker(worker);
|
|
54
69
|
worker.on('message', function(message) {
|
|
55
70
|
if(message === MSG_REQUEST_NEW_TASK){
|
|
56
|
-
queue.enqueue(
|
|
71
|
+
queue.enqueue(async ()=>{
|
|
72
|
+
return TaskMgr.updateNewTasks();
|
|
73
|
+
});//use queue to make sure no I/O conflict
|
|
57
74
|
queue.enqueue(async () => {
|
|
58
|
-
TaskMgr.popNewTask().then((subTask)=>{
|
|
75
|
+
return TaskMgr.popNewTask().then((subTask)=>{
|
|
59
76
|
if(!subTask){
|
|
60
77
|
//no tasks left
|
|
61
78
|
console.log('[Master]: no tasks left!');
|
|
62
79
|
//console.log('workers', cluster.workers);
|
|
63
80
|
if(config.autoCloseAfterCompletion){
|
|
64
|
-
worker
|
|
81
|
+
killWorker(worker);
|
|
65
82
|
}else{//waiting for new tasks
|
|
66
83
|
worker.send(MSG_NO_TASK_FOUND,()=>{}, {
|
|
67
84
|
keepOpen: (typeof config.keepOpen === 'undefined') ? false : config.keepOpen
|
|
@@ -69,6 +86,12 @@ const start = (config)=>{
|
|
|
69
86
|
}
|
|
70
87
|
//
|
|
71
88
|
}else{
|
|
89
|
+
|
|
90
|
+
let terminateData = {taskCount,subTask,config, id: worker.id};
|
|
91
|
+
if(USER_CONFIG.shouldTerminate && USER_CONFIG.shouldTerminate(terminateData)===true) {
|
|
92
|
+
killAllWorkers();
|
|
93
|
+
return process.exit(0);
|
|
94
|
+
}
|
|
72
95
|
//send new tasks to the worker
|
|
73
96
|
worker.send({
|
|
74
97
|
taskCount,
|
|
@@ -99,7 +122,7 @@ const start = (config)=>{
|
|
|
99
122
|
setTimeout(()=>{
|
|
100
123
|
console.log('[Master]: all workers are done, process exit.')
|
|
101
124
|
process.exit(0);
|
|
102
|
-
},
|
|
125
|
+
}, 10);
|
|
103
126
|
}
|
|
104
127
|
});
|
|
105
128
|
}else{
|
package/workers/TaskMgr.js
CHANGED
|
@@ -34,7 +34,7 @@ const TaskMgr = {
|
|
|
34
34
|
initFolders:()=>{
|
|
35
35
|
let {taskRootFolder, masterTaskId} = main_config;
|
|
36
36
|
taskFolder = pathutil.resolve(taskRootFolder, masterTaskId);
|
|
37
|
-
if(fs.existsSync(taskFolder)){
|
|
37
|
+
if(fs.existsSync(taskFolder) && !(main_config.__resume || main_config.__restart)){
|
|
38
38
|
let files = fs.readdirSync(taskFolder);
|
|
39
39
|
if(files.length > 0){
|
|
40
40
|
console.log('[FATAL] taskRootFolder already exist and not empty, delete it and try again: ', taskFolder);
|
package/workers/index.js
CHANGED
|
@@ -1,8 +1,43 @@
|
|
|
1
|
+
const pathUtil = require('path');
|
|
1
2
|
const Multithread = require('./Multithread');
|
|
2
3
|
const backwardv1 = require('../utils/backward-v1')
|
|
3
4
|
|
|
4
|
-
const
|
|
5
|
+
const start = (config)=>{
|
|
5
6
|
config = backwardv1.v1tov2(config);
|
|
6
7
|
Multithread.start(config);
|
|
7
8
|
};
|
|
9
|
+
const resume = (config)=>{
|
|
10
|
+
config = backwardv1.v1tov2(config);
|
|
11
|
+
let {taskFolder} = config;
|
|
12
|
+
if(!taskFolder){
|
|
13
|
+
console.log('[ERROR]', 'method resume need param "taskFolder"')
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
let pathinfo = pathUtil.parse(taskFolder);
|
|
17
|
+
let taskId = pathinfo.name;
|
|
18
|
+
let taskRootFolder = pathinfo.dir;
|
|
19
|
+
|
|
20
|
+
config.taskId = taskId;
|
|
21
|
+
config.taskRootFolder = taskRootFolder;
|
|
22
|
+
config.__resume = true;
|
|
23
|
+
|
|
24
|
+
Multithread.start(config);
|
|
25
|
+
};
|
|
26
|
+
const restart = (config)=>{
|
|
27
|
+
config = backwardv1.v1tov2(config);
|
|
28
|
+
let {taskFolder} = config;
|
|
29
|
+
if(!taskFolder){
|
|
30
|
+
console.log('[ERROR]', 'method resume need param "taskFolder"')
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const multiTasks = (config)=>{
|
|
36
|
+
start(config);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
multiTasks.start = start;
|
|
40
|
+
multiTasks.restart = restart;
|
|
41
|
+
multiTasks.resume = resume;
|
|
42
|
+
|
|
8
43
|
module.exports = multiTasks;
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
let fs = require('fs');
|
|
2
|
-
let pathutil = require('path');
|
|
3
|
-
const { spawn, exec } = require('child_process');
|
|
4
|
-
let SuperConsumer = require('../index').SuperConsumer;
|
|
5
|
-
let localUtil = require('./util');
|
|
6
|
-
const makeDir = require('../utils/makedir');
|
|
7
|
-
|
|
8
|
-
let thisroot = pathutil.parse(__filename).dir;
|
|
9
|
-
let garbagedir = pathutil.resolve(thisroot,`./tmp-garbage`);
|
|
10
|
-
makeDir.sync(garbagedir);
|
|
11
|
-
|
|
12
|
-
let loadTaskFile = (dir)=>{
|
|
13
|
-
var results = []
|
|
14
|
-
var list = fs.readdirSync(dir);
|
|
15
|
-
list.forEach(function(file) {
|
|
16
|
-
var stat;
|
|
17
|
-
try{
|
|
18
|
-
stat = fs.statSync(pathutil.resolve(dir, file))
|
|
19
|
-
}catch(e){
|
|
20
|
-
//Must try-catch, the file maybe deleted by other process
|
|
21
|
-
}
|
|
22
|
-
if (stat && !stat.isDirectory()) results.push({
|
|
23
|
-
file,
|
|
24
|
-
fpath: pathutil.resolve(dir, file)
|
|
25
|
-
});
|
|
26
|
-
})
|
|
27
|
-
//console.log(results);
|
|
28
|
-
return results;
|
|
29
|
-
};
|
|
30
|
-
let processTask = (moduleName, requestVersion, callback)=>{
|
|
31
|
-
let outputs = [];
|
|
32
|
-
let ls = spawn(`ls`, [], {cwd: garbagedir, shell: true});
|
|
33
|
-
ls.stdout.on('data', (data) => {
|
|
34
|
-
let stdout = data.toString();
|
|
35
|
-
outputs.push(stdout);
|
|
36
|
-
//console.log('[stdout]', stdout)
|
|
37
|
-
});
|
|
38
|
-
ls.stderr.on('data', (data) => {
|
|
39
|
-
let stdout = data.toString();
|
|
40
|
-
//console.log('[stderr]', stdout)
|
|
41
|
-
outputs.push(stdout);
|
|
42
|
-
});
|
|
43
|
-
ls.on('close', (code) => {
|
|
44
|
-
//console.log('[close]', code)
|
|
45
|
-
// if(code === 1) {
|
|
46
|
-
// console.log('[error], checkout failed!!')
|
|
47
|
-
// }
|
|
48
|
-
let succ = true;
|
|
49
|
-
let logTxt = outputs.join('');
|
|
50
|
-
|
|
51
|
-
if(logTxt.indexOf('ERR!')>=0 && logTxt.match(/ERR\!/g)) {
|
|
52
|
-
succ = false;
|
|
53
|
-
}
|
|
54
|
-
let logJson;
|
|
55
|
-
try{
|
|
56
|
-
logJson = JSON.parse(logTxt);
|
|
57
|
-
}catch(e){
|
|
58
|
-
console.log(e)
|
|
59
|
-
console.log(`at===`, moduleName, requestVersion)
|
|
60
|
-
console.log(`logTxt===`, logTxt)
|
|
61
|
-
succ = false;
|
|
62
|
-
}
|
|
63
|
-
if(succ && logJson){
|
|
64
|
-
if(!Array.isArray(logJson)){
|
|
65
|
-
logJson = [logJson];
|
|
66
|
-
};
|
|
67
|
-
let data = {
|
|
68
|
-
response: logJson,
|
|
69
|
-
__info__: {
|
|
70
|
-
moduleName,
|
|
71
|
-
requestVersion,
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
callback(true, data);
|
|
75
|
-
}else{
|
|
76
|
-
callback(false, logTxt);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
let _do = (mainTaskInfo, actions, callback)=>{
|
|
83
|
-
let{dynamicTasksFolderNew, dynamicTasksFolderSucc, dynamicTasksFolderFail} = mainTaskInfo.defination;
|
|
84
|
-
let tasks = loadTaskFile(dynamicTasksFolderNew);
|
|
85
|
-
if(tasks.length === 0) return callback({data:'hahaha'+Math.random()});//stop!
|
|
86
|
-
|
|
87
|
-
tasks = localUtil.shuffleAnArray(tasks);//avoid file IO conflicts
|
|
88
|
-
|
|
89
|
-
let task;
|
|
90
|
-
let data;
|
|
91
|
-
while(!data){
|
|
92
|
-
task = tasks.shift();
|
|
93
|
-
try{
|
|
94
|
-
data = JSON.parse(fs.readFileSync(task.fpath, 'utf8'));
|
|
95
|
-
}catch(e){
|
|
96
|
-
console.log('xxxx')
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if(task && data){
|
|
101
|
-
let fpath = task.fpath;
|
|
102
|
-
{
|
|
103
|
-
//processing...
|
|
104
|
-
let {moduleName, requestVersion, fullnameMd5} = data.info;
|
|
105
|
-
let oldfPath = fpath;
|
|
106
|
-
let newfPath = pathutil.resolve(dynamicTasksFolderNew, `${fullnameMd5}.json`);
|
|
107
|
-
let succfPath = pathutil.resolve(dynamicTasksFolderSucc, `${fullnameMd5}.json`);
|
|
108
|
-
let errfPath = pathutil.resolve(dynamicTasksFolderFail, `${fullnameMd5}.json`);
|
|
109
|
-
if(fs.existsSync(succfPath) || fs.existsSync(errfPath)) {
|
|
110
|
-
console.log('exist...', process.pid, fullnameMd5);
|
|
111
|
-
if(fs.existsSync(newfPath))
|
|
112
|
-
try{
|
|
113
|
-
fs.unlinkSync(newfPath);
|
|
114
|
-
}catch(e){
|
|
115
|
-
console.log('remove failed', process.pid, newfPath, e);
|
|
116
|
-
}
|
|
117
|
-
_do(mainTaskInfo, actions, callback);
|
|
118
|
-
}else {
|
|
119
|
-
console.log('processing...', process.pid, fpath);
|
|
120
|
-
processTask(moduleName, requestVersion, (succ, logJson)=>{
|
|
121
|
-
if(succ){
|
|
122
|
-
fs.writeFileSync(succfPath, JSON.stringify(logJson));
|
|
123
|
-
logJson.response.forEach((item)=>{
|
|
124
|
-
if(item.dependencies){
|
|
125
|
-
for(let module2 in item.dependencies){
|
|
126
|
-
let version2 = item.dependencies[module2];
|
|
127
|
-
console.log('found new task', module2, version2);
|
|
128
|
-
localUtil.createNewTask(module2, version2, dynamicTasksFolderNew);//find new one, create a new task file
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
}else{
|
|
133
|
-
console.log('ERR! failed', moduleName, requestVersion);
|
|
134
|
-
fs.writeFileSync(pathutil.resolve(dynamicTasksFolderFail, `${fullnameMd5}.json`), JSON.stringify({
|
|
135
|
-
moduleName, requestVersion,
|
|
136
|
-
msg: logJson
|
|
137
|
-
}));
|
|
138
|
-
}
|
|
139
|
-
_do(mainTaskInfo, actions, callback);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
if(fs.existsSync(oldfPath)){
|
|
143
|
-
try{
|
|
144
|
-
fs.unlinkSync(oldfPath);
|
|
145
|
-
}catch(e){
|
|
146
|
-
console.log('remove failed', process.pid, oldfPath, e);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}else{
|
|
151
|
-
console.log('__done2', process.pid)
|
|
152
|
-
return callback({data:'hahaha'+Math.random()});//stop!
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
class TestConsumer extends SuperConsumer {
|
|
158
|
-
// constructor
|
|
159
|
-
constructor(taskname, parentfolder) {
|
|
160
|
-
super(taskname, parentfolder)
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
setTaskTrunkInfo(trunkInfo){
|
|
164
|
-
this.trunkInfo = trunkInfo;
|
|
165
|
-
}
|
|
166
|
-
run (mainTaskInfo, subTaskInfo, taskInfo, callback){
|
|
167
|
-
//console.log(`this.trunkInfo===`, this.trunkInfo)
|
|
168
|
-
let actions = subTaskInfo.actions;
|
|
169
|
-
mainTaskInfo.defination = this.trunkInfo;
|
|
170
|
-
_do(mainTaskInfo, actions, (result)=>{
|
|
171
|
-
callback(result)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
module.exports = TestConsumer;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
let SuperProducer = require('../index').SuperProducer;
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
let pathutil = require('path');
|
|
4
|
-
|
|
5
|
-
let thisroot = pathutil.parse(__filename).dir;
|
|
6
|
-
|
|
7
|
-
let localUtil = require('./util')
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
let createInitialTasks = (info)=>{
|
|
11
|
-
let succList = JSON.parse(fs.readFileSync(pathutil.resolve(thisroot,'../tmp/version_succList.json'), 'utf8'));
|
|
12
|
-
//succList = succList.slice(0, 20);
|
|
13
|
-
succList.forEach((item)=>{
|
|
14
|
-
let {moduleName, requestVersion} = item;
|
|
15
|
-
localUtil.createNewTask(moduleName, requestVersion, info.dynamicTasksFolderNew);
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class TestProducer extends SuperProducer {
|
|
22
|
-
|
|
23
|
-
// constructor
|
|
24
|
-
constructor(taskname, parentfolder) {
|
|
25
|
-
super(taskname, parentfolder)
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
setTaskTrunkInfo(trunkInfo){
|
|
29
|
-
this.trunkInfo = trunkInfo;
|
|
30
|
-
}
|
|
31
|
-
getAllActions() {
|
|
32
|
-
createInitialTasks(this.trunkInfo);
|
|
33
|
-
return new Promise((resolve, reject)=>{
|
|
34
|
-
let trunkInfo = this.trunkInfo;
|
|
35
|
-
let {NUMBER_OF_WORKS} = trunkInfo;
|
|
36
|
-
//console.log(this.trunkInfo)
|
|
37
|
-
//throw repos.length+'ff'+repos2.length
|
|
38
|
-
//here, IGNORED_repoRegexStringList
|
|
39
|
-
let alltasks = []
|
|
40
|
-
for(let i=0;i<NUMBER_OF_WORKS;i++){//the task was driven by files, not here
|
|
41
|
-
alltasks.push({
|
|
42
|
-
num:i
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
resolve(alltasks);
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
module.exports = TestProducer;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
let fs = require('fs');
|
|
2
|
-
let pathutil = require('path');
|
|
3
|
-
let makeDir = require('../utils/makedir');
|
|
4
|
-
let RunnerProducer = require('./RunnerProducer');//switch to require from node_modules in your project
|
|
5
|
-
let RunnerConsumer = require('./RunnerConsumer');//switch to require from node_modules in your project
|
|
6
|
-
|
|
7
|
-
let thisroot = pathutil.parse(__filename).dir;
|
|
8
|
-
let taskId = `workers_of_${Math.random()}`;
|
|
9
|
-
let multi_task_parent_folder = pathutil.resolve(thisroot, `../../example2_dynamicly_increasing`);
|
|
10
|
-
|
|
11
|
-
let producer = new RunnerProducer(taskId, multi_task_parent_folder)
|
|
12
|
-
let consumer = new RunnerConsumer();
|
|
13
|
-
let master = require('../index').master;
|
|
14
|
-
|
|
15
|
-
console.log(producer.getTaskName())
|
|
16
|
-
//return;
|
|
17
|
-
|
|
18
|
-
let NUMBER_OF_WORKS = 5;//LOCK NUMBER OF WORKERS
|
|
19
|
-
|
|
20
|
-
let taskConfig = {
|
|
21
|
-
NUMBER_OF_WORKS,
|
|
22
|
-
dynamicTasksFolderNew: pathutil.resolve(multi_task_parent_folder, `./dynamicTasks-NEW`),
|
|
23
|
-
dynamicTasksFolderSucc: pathutil.resolve(multi_task_parent_folder, `./dynamicTasks-SUCC`),
|
|
24
|
-
dynamicTasksFolderFail: pathutil.resolve(multi_task_parent_folder, `./dynamicTasks-FAIL`),
|
|
25
|
-
}
|
|
26
|
-
makeDir.sync(taskConfig.dynamicTasksFolderNew)
|
|
27
|
-
makeDir.sync(taskConfig.dynamicTasksFolderSucc)
|
|
28
|
-
makeDir.sync(taskConfig.dynamicTasksFolderFail)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
producer.setTaskTrunkInfo(taskConfig);
|
|
32
|
-
consumer.setTaskTrunkInfo(taskConfig)
|
|
33
|
-
master.run(producer, consumer, {
|
|
34
|
-
quotaOfEachTask:1, //<--Lock as one
|
|
35
|
-
numberOfWorkers:NUMBER_OF_WORKS
|
|
36
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
const md5 = require('md5');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
let pathutil = require('path');
|
|
4
|
-
|
|
5
|
-
let getFileName = (moduleName, requestVersion)=>{
|
|
6
|
-
let fullname = `${moduleName}@${requestVersion}`;
|
|
7
|
-
let fullnameMd5 = md5(fullname);
|
|
8
|
-
return fullnameMd5;
|
|
9
|
-
};
|
|
10
|
-
let createNewTask = (moduleName, requestVersion, dynamicTasksFolderNew)=>{
|
|
11
|
-
let fullnameMd5 = getFileName(moduleName, requestVersion);
|
|
12
|
-
fs.writeFileSync(pathutil.resolve(dynamicTasksFolderNew, `./${fullnameMd5}.json`), JSON.stringify({
|
|
13
|
-
info:{
|
|
14
|
-
moduleName,
|
|
15
|
-
requestVersion,
|
|
16
|
-
fullnameMd5,
|
|
17
|
-
}
|
|
18
|
-
}));
|
|
19
|
-
};
|
|
20
|
-
function shuffleAnArray(array) {
|
|
21
|
-
if(array.length === 0 || array.length === 1) return array;
|
|
22
|
-
let currentIndex = array.length, randomIndex;
|
|
23
|
-
|
|
24
|
-
// While there remain elements to shuffle.
|
|
25
|
-
while (currentIndex > 0) {
|
|
26
|
-
|
|
27
|
-
// Pick a remaining element.
|
|
28
|
-
randomIndex = Math.floor(Math.random() * currentIndex);
|
|
29
|
-
currentIndex--;
|
|
30
|
-
|
|
31
|
-
// And swap it with the current element.
|
|
32
|
-
let tmp = array[currentIndex];
|
|
33
|
-
array[currentIndex] = array[randomIndex];
|
|
34
|
-
array[randomIndex] = tmp;
|
|
35
|
-
|
|
36
|
-
// [array[currentIndex], array[randomIndex]] = [
|
|
37
|
-
// array[randomIndex], array[currentIndex]];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return array;
|
|
41
|
-
}
|
|
42
|
-
module.exports = {
|
|
43
|
-
createNewTask,
|
|
44
|
-
getFileName,
|
|
45
|
-
shuffleAnArray
|
|
46
|
-
};
|