multi-tasks 2.0.1 → 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 +3 -1
- package/examples/example0/run-readme.js +1 -1
- package/examples/example0/run.js +2 -2
- package/package.json +1 -1
- package/utils/asyncQueue.js +7 -3
- package/utils/makedir.js +4 -0
- package/workers/Multithread.js +22 -1
- package/workers/TaskMgr.js +9 -5
- 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,7 @@ node examples/example1/run
|
|
|
113
114
|
|
|
114
115
|
Changelog:
|
|
115
116
|
|
|
117
|
+
- 2.0.2 new feature: support shouldTerminate
|
|
116
118
|
- 2.0.1 Avoid possible I/O conflicts.
|
|
117
119
|
- 2.0.0 Rewritten with a new architecture to support dynamic tasks.
|
|
118
120
|
- 1.2.8 Fix: create task folder failed on MacOS
|
|
@@ -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,13 +40,13 @@ 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
|
|
47
47
|
taskId: 'my-task',
|
|
48
48
|
numberOfWorkers: 3, //Assign how many workers are working in parallel
|
|
49
|
-
autoCloseAfterCompletion: true,
|
|
49
|
+
//autoCloseAfterCompletion: true,
|
|
50
50
|
onFinish: (report)=>{
|
|
51
51
|
console.log('finish callback', report);
|
|
52
52
|
}
|
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/utils/makedir.js
CHANGED
|
@@ -39,10 +39,14 @@ function getDirectFiles(dir, callback) {
|
|
|
39
39
|
files.forEach(file => {
|
|
40
40
|
const filePath = path.join(dir, file);
|
|
41
41
|
//console.log(filePath)
|
|
42
|
+
try{
|
|
42
43
|
let stats = fs.statSync(filePath);
|
|
43
44
|
if (stats.isFile()) {
|
|
44
45
|
childrenfiles.push(file);
|
|
45
46
|
}
|
|
47
|
+
}catch(e){
|
|
48
|
+
//
|
|
49
|
+
}
|
|
46
50
|
});
|
|
47
51
|
callback(childrenfiles);
|
|
48
52
|
});
|
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);
|
|
@@ -63,7 +78,7 @@ const start = (config)=>{
|
|
|
63
78
|
console.log('[Master]: no tasks left!');
|
|
64
79
|
//console.log('workers', cluster.workers);
|
|
65
80
|
if(config.autoCloseAfterCompletion){
|
|
66
|
-
worker
|
|
81
|
+
killWorker(worker);
|
|
67
82
|
}else{//waiting for new tasks
|
|
68
83
|
worker.send(MSG_NO_TASK_FOUND,()=>{}, {
|
|
69
84
|
keepOpen: (typeof config.keepOpen === 'undefined') ? false : config.keepOpen
|
|
@@ -71,6 +86,12 @@ const start = (config)=>{
|
|
|
71
86
|
}
|
|
72
87
|
//
|
|
73
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
|
+
}
|
|
74
95
|
//send new tasks to the worker
|
|
75
96
|
worker.send({
|
|
76
97
|
taskCount,
|
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);
|
|
@@ -95,13 +95,15 @@ const TaskMgr = {
|
|
|
95
95
|
loadNewTasks:()=>{
|
|
96
96
|
const {masterTaskId, taskFolderNew} = main_config;
|
|
97
97
|
return new Promise((resolve)=>{
|
|
98
|
-
console.log('get1')
|
|
99
98
|
makeDir.getDirectFiles(taskFolderNew, (taskFiles)=>{
|
|
100
99
|
taskFiles.forEach((filename)=>{
|
|
101
100
|
let fpath = pathutil.resolve(taskFolderNew, filename);
|
|
102
101
|
let fcontent;
|
|
102
|
+
try{
|
|
103
103
|
fcontent = fs.readFileSync(fpath, 'utf-8');
|
|
104
|
-
|
|
104
|
+
}catch(e){
|
|
105
|
+
console.log('[WARN]', `file not found`, fpath)
|
|
106
|
+
}
|
|
105
107
|
if(fcontent){
|
|
106
108
|
let task = JSON.parse(fcontent);
|
|
107
109
|
allSubTasks.new.push(task);
|
|
@@ -150,7 +152,6 @@ const TaskMgr = {
|
|
|
150
152
|
getTaskFiles:(type, callback)=>{
|
|
151
153
|
let rootdir = main_config.progressRootFolder;
|
|
152
154
|
let targetFolder = pathutil.resolve(rootdir, `./${type}`);
|
|
153
|
-
console.log('get2')
|
|
154
155
|
makeDir.getDirectFiles(targetFolder, (files)=>{
|
|
155
156
|
callback(files);
|
|
156
157
|
});
|
|
@@ -160,11 +161,14 @@ const TaskMgr = {
|
|
|
160
161
|
let {progressRootFolder} = main_config;
|
|
161
162
|
let oldPath = pathutil.resolve(progressRootFolder, `./${from}/${subid}.task.json`);
|
|
162
163
|
let newPath = pathutil.resolve(progressRootFolder, `./${to}/${subid}.task.json`);
|
|
163
|
-
|
|
164
|
+
try{
|
|
164
165
|
fs.rename(oldPath, newPath, (err) => {
|
|
165
166
|
//if (err) throw err;
|
|
166
167
|
callback(newPath);
|
|
167
168
|
});
|
|
169
|
+
}catch(e){
|
|
170
|
+
callback(newPath);
|
|
171
|
+
}
|
|
168
172
|
},
|
|
169
173
|
saveTaskResult:(subid, hasError, data)=>{
|
|
170
174
|
let {taskFolderResult, taskFolderResultFailed} = main_config;
|
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
|
-
};
|