multi-tasks 2.0.4 → 2.0.6
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 +48 -36
- package/package.json +1 -1
- package/examples/example1/RunnerConsumer.js +0 -26
- package/examples/example1/RunnerProducer.js +0 -35
- package/examples/example1/run.js +0 -9
- package/examples/example2/RunnerConsumer.js +0 -40
- package/examples/example2/RunnerProducer.js +0 -35
- package/examples/example2/run.js +0 -23
package/README.md
CHANGED
|
@@ -14,7 +14,8 @@ How to use:
|
|
|
14
14
|
let multiTasks = require('multi-tasks').multiTasks;
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
//Step1,
|
|
17
|
+
//Step1, if you have tasks that need to be executed simultaneously,
|
|
18
|
+
// provide them as an array, multi-tasks will automatically split them and execute.
|
|
18
19
|
let alltasks = [];
|
|
19
20
|
for(let i=0;i<50;i++){
|
|
20
21
|
alltasks.push({
|
|
@@ -23,14 +24,44 @@ for(let i=0;i<50;i++){
|
|
|
23
24
|
});
|
|
24
25
|
};
|
|
25
26
|
|
|
26
|
-
//Step2,
|
|
27
|
+
//Step2, provide a function to process a certain sub-task and return the result data
|
|
27
28
|
let processTask = (task, helper)=>{
|
|
28
29
|
let {taskCount} = task;
|
|
29
30
|
|
|
30
31
|
return 'a result which is not a promise';
|
|
31
32
|
};
|
|
32
33
|
|
|
33
|
-
//
|
|
34
|
+
//Step3, run!
|
|
35
|
+
multiTasks({
|
|
36
|
+
initialTasks: alltasks,
|
|
37
|
+
processTask,
|
|
38
|
+
taskRootFolder: `../examples-tmp-data/example0`, //a directory to store progress and results files, you can check the progress here
|
|
39
|
+
taskId: 'my-task',
|
|
40
|
+
numberOfWorkers: 3, //how many workers are working in parallel
|
|
41
|
+
//autoCloseAfterCompletion: true, //if you have dynamically generated new tasks, put this as false
|
|
42
|
+
shouldTerminate:(info)=>{
|
|
43
|
+
//return true if you need to terminate the whole process
|
|
44
|
+
},
|
|
45
|
+
onFinish: (report)=>{
|
|
46
|
+
console.log('finish callback', report);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Have a try:
|
|
53
|
+
|
|
54
|
+
```shell
|
|
55
|
+
node examples/example0/run
|
|
56
|
+
node examples/example1/run
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
More about the task processing function
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
//Example1, return a promise for async processes,
|
|
63
|
+
// you can return a promise or a non-promise result,
|
|
64
|
+
// all result data can be found in the results/succ folder
|
|
34
65
|
let processTask = (task, helper)=>{
|
|
35
66
|
let {taskCount} = task;
|
|
36
67
|
|
|
@@ -41,13 +72,13 @@ let processTask = (task, helper)=>{
|
|
|
41
72
|
})
|
|
42
73
|
};
|
|
43
74
|
|
|
44
|
-
//
|
|
75
|
+
//Example2, dynamically create a new task while processing
|
|
45
76
|
let processTask = (task, helper)=>{
|
|
46
77
|
let {taskCount} = task;
|
|
47
78
|
|
|
48
79
|
|
|
49
80
|
if(taskCount % 2 === 0){
|
|
50
|
-
helper.createNewTasks({//
|
|
81
|
+
helper.createNewTasks({//dynamically create a new task if find something new while processing
|
|
51
82
|
msg:'a new task'
|
|
52
83
|
});
|
|
53
84
|
return;
|
|
@@ -60,23 +91,27 @@ let processTask = (task, helper)=>{
|
|
|
60
91
|
})
|
|
61
92
|
};
|
|
62
93
|
|
|
63
|
-
//
|
|
94
|
+
//Example3, generate/throw exceptions in a task method
|
|
64
95
|
let processTask = (task, helper)=>{
|
|
65
96
|
let {taskCount} = task;
|
|
66
97
|
|
|
67
98
|
//This is the demo of exceptions/errors, they will be captured and saved in the results/errors folder
|
|
68
99
|
if(taskCount===3) throw 'exception';
|
|
69
|
-
if(taskCount===4) return Promise.reject({err:'a test error'})
|
|
70
|
-
if(taskCount===5) aaa = bbb
|
|
100
|
+
if(taskCount===4) return Promise.reject({err:'a test error'});//use Promise.reject method
|
|
101
|
+
if(taskCount===5) aaa = bbb;//this undefined exception will be captured by multi-tasks
|
|
102
|
+
|
|
103
|
+
return {data:'succ'};
|
|
104
|
+
}
|
|
105
|
+
|
|
71
106
|
|
|
72
|
-
|
|
107
|
+
//Example4, dynamically create a new task while processing
|
|
108
|
+
let processTask = (task, helper)=>{
|
|
109
|
+
let {taskCount} = task;
|
|
73
110
|
|
|
74
|
-
//by default, you should return a promise, all returned data can be found in the results/succ folder
|
|
75
|
-
//but to return a non-promise result is also OK, see above
|
|
76
111
|
return new Promise((resolve, reject)=>{
|
|
77
112
|
setTimeout(()=>{
|
|
78
113
|
if(taskCount % 2 === 0){
|
|
79
|
-
helper.createNewTasks({//
|
|
114
|
+
helper.createNewTasks({//create a new task if needed
|
|
80
115
|
msg:'a new task'
|
|
81
116
|
});
|
|
82
117
|
resolve()
|
|
@@ -88,34 +123,11 @@ let processTask = (task, helper)=>{
|
|
|
88
123
|
}, 10)
|
|
89
124
|
})
|
|
90
125
|
}
|
|
91
|
-
|
|
92
|
-
//Step3, run!
|
|
93
|
-
multiTasks({
|
|
94
|
-
initialTasks: alltasks,
|
|
95
|
-
processTask,
|
|
96
|
-
taskRootFolder: `../examples-tmp-data/example0`, //a directory to store progress and results files, you can check the progress here
|
|
97
|
-
taskId: 'my-task',
|
|
98
|
-
numberOfWorkers: 3, //Assign how many workers are working in parallel
|
|
99
|
-
//autoCloseAfterCompletion: true, //if you have dynamically generated new tasks, put this as false
|
|
100
|
-
shouldTerminate:(info)=>{
|
|
101
|
-
//return true if you need to terminate the whole process
|
|
102
|
-
},
|
|
103
|
-
onFinish: (report)=>{
|
|
104
|
-
console.log('finish callback', report);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Have a try:
|
|
111
|
-
|
|
112
|
-
```shell
|
|
113
|
-
node examples/example0/run
|
|
114
|
-
node examples/example1/run
|
|
115
126
|
```
|
|
116
127
|
|
|
117
128
|
Changelog:
|
|
118
129
|
|
|
130
|
+
- 2.0.5 Update readme examples
|
|
119
131
|
- 2.0.4 Support resume from a failed task
|
|
120
132
|
- 2.0.3 Fix: mkdir bug on windows
|
|
121
133
|
- 2.0.2 new feature: support shouldTerminate
|
package/package.json
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
let SuperConsumer = require('../../index').SuperConsumer;
|
|
2
|
-
|
|
3
|
-
class TestConsumer extends SuperConsumer {
|
|
4
|
-
|
|
5
|
-
processTask(actionData){
|
|
6
|
-
console.log(`processing data:`, actionData);
|
|
7
|
-
//you can also return a data instead of a promise object
|
|
8
|
-
let {index} = actionData;
|
|
9
|
-
if(index===3) throw 'exception';
|
|
10
|
-
if(index===4) return Promise.reject({err:'a test error'});
|
|
11
|
-
return new Promise((resolve) => {
|
|
12
|
-
setTimeout(() => {
|
|
13
|
-
let result = {
|
|
14
|
-
task:{
|
|
15
|
-
...actionData,
|
|
16
|
-
},
|
|
17
|
-
result: {
|
|
18
|
-
message: 'this is a result from a demo, random data=' + Math.random()
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
resolve(result);
|
|
22
|
-
}, 100);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
module.exports = TestConsumer;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
let SuperProducer = require('../../index').SuperProducer;
|
|
2
|
-
class TestProducer extends SuperProducer {
|
|
3
|
-
|
|
4
|
-
// constructor
|
|
5
|
-
constructor(taskname, parentfolder) {
|
|
6
|
-
super(taskname, parentfolder)
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
setTaskTrunkInfo(trunkInfo){
|
|
10
|
-
this.trunkInfo = trunkInfo;
|
|
11
|
-
}
|
|
12
|
-
getAllActions() {
|
|
13
|
-
/**
|
|
14
|
-
* Generate all your tasks in this method, return as an array;
|
|
15
|
-
* These data will be allocated to multiple threads (workers) for running;
|
|
16
|
-
* You can obtain each of the data and process it in the 'processTask' method of your consumer.
|
|
17
|
-
*
|
|
18
|
-
* **/
|
|
19
|
-
|
|
20
|
-
return new Promise((resolve, reject)=>{
|
|
21
|
-
let trunkInfo = this.trunkInfo;
|
|
22
|
-
let alltasks = []
|
|
23
|
-
for(let i=0;i<200;i++){
|
|
24
|
-
let task_props = {
|
|
25
|
-
index: i,
|
|
26
|
-
name: `task-${i}`,
|
|
27
|
-
description: `This prop is for a subtask`
|
|
28
|
-
};
|
|
29
|
-
alltasks.push(task_props);
|
|
30
|
-
}
|
|
31
|
-
resolve(alltasks);//return all your tasks as an array
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
module.exports = TestProducer;
|
package/examples/example1/run.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
let RunnerProducer = require('./RunnerProducer');//You need to provide a Producer to return all subtasks, multi-tasks will automatically split them and execute them in a multi-threaded manner
|
|
2
|
-
let RunnerConsumer = require('./RunnerConsumer');//You need to provide a Consumer to process a certain sub-task and return the processed data
|
|
3
|
-
let master = require('../../index').master;
|
|
4
|
-
|
|
5
|
-
master.start(RunnerProducer, RunnerConsumer, {
|
|
6
|
-
multi_task_parent_folder: `C:/tmp-demo`,
|
|
7
|
-
quotaOfEachTask:2, //The number of tasks assigned to each worker
|
|
8
|
-
numberOfWorkers: 6
|
|
9
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
let SuperConsumer = require('../../index').SuperConsumer;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
let _do = (mainTaskInfo, actions, callback)=>{
|
|
5
|
-
if(actions.length === 0) return callback({
|
|
6
|
-
data:'subtask finished, random data='+Math.random()
|
|
7
|
-
});
|
|
8
|
-
let actionData = actions.shift();
|
|
9
|
-
|
|
10
|
-
//start to write your process code here
|
|
11
|
-
|
|
12
|
-
console.log('actionData', actionData)
|
|
13
|
-
|
|
14
|
-
//end of your process code.
|
|
15
|
-
|
|
16
|
-
//trigger next task
|
|
17
|
-
_do(mainTaskInfo, actions, callback);
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class TestConsumer extends SuperConsumer {
|
|
22
|
-
|
|
23
|
-
// constructor
|
|
24
|
-
constructor(taskname, parentfolder) {
|
|
25
|
-
super(taskname, parentfolder)
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
setTaskTrunkInfo(trunkInfo){
|
|
29
|
-
this.trunkInfo = trunkInfo;
|
|
30
|
-
}
|
|
31
|
-
run (mainTaskInfo, subTaskInfo, taskInfo, callback){
|
|
32
|
-
let actions = subTaskInfo.actions;
|
|
33
|
-
mainTaskInfo.defination = this.trunkInfo.defination;
|
|
34
|
-
_do(mainTaskInfo, actions, (result)=>{
|
|
35
|
-
callback(result)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
module.exports = TestConsumer;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
let SuperProducer = require('../../index').SuperProducer;
|
|
2
|
-
class TestProducer extends SuperProducer {
|
|
3
|
-
|
|
4
|
-
// constructor
|
|
5
|
-
constructor(taskname, parentfolder) {
|
|
6
|
-
super(taskname, parentfolder)
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
setTaskTrunkInfo(trunkInfo){
|
|
10
|
-
this.trunkInfo = trunkInfo;
|
|
11
|
-
}
|
|
12
|
-
getAllActions() {
|
|
13
|
-
/**
|
|
14
|
-
* Generate all your tasks in this method, return as an array;
|
|
15
|
-
* These data will be allocated to multiple threads (workers) for running;
|
|
16
|
-
* You can obtain each of the data and process it in the 'processTask' method of your consumer.
|
|
17
|
-
*
|
|
18
|
-
* **/
|
|
19
|
-
|
|
20
|
-
return new Promise((resolve, reject)=>{
|
|
21
|
-
let trunkInfo = this.trunkInfo;
|
|
22
|
-
let alltasks = []
|
|
23
|
-
for(let i=0;i<200;i++){
|
|
24
|
-
let task_props = {
|
|
25
|
-
index: i,
|
|
26
|
-
name: `task-${i}`,
|
|
27
|
-
description: `This prop is for a subtask`
|
|
28
|
-
};
|
|
29
|
-
alltasks.push(task_props);
|
|
30
|
-
}
|
|
31
|
-
resolve(alltasks);//return all your tasks as an array
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
module.exports = TestProducer;
|
package/examples/example2/run.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
let RunnerProducer = require('./RunnerProducer');//switch to require from node_modules in your project
|
|
2
|
-
let RunnerConsumer = require('./RunnerConsumer');//switch to require from node_modules in your project
|
|
3
|
-
|
|
4
|
-
let taskId = Math.random()+'';
|
|
5
|
-
let multi_task_parent_folder = `C:/tmp-demo`;
|
|
6
|
-
|
|
7
|
-
let producer = new RunnerProducer(`workers_of_${taskId}`, multi_task_parent_folder)
|
|
8
|
-
let consumer = new RunnerConsumer();
|
|
9
|
-
let master = require('../../index').master;
|
|
10
|
-
|
|
11
|
-
console.log(producer.getTaskName())
|
|
12
|
-
//return;
|
|
13
|
-
|
|
14
|
-
let taskConfig = {
|
|
15
|
-
multi_task_parent_folder
|
|
16
|
-
}
|
|
17
|
-
//console.log(resp)
|
|
18
|
-
producer.setTaskTrunkInfo(taskConfig);
|
|
19
|
-
consumer.setTaskTrunkInfo(taskConfig)
|
|
20
|
-
master.run(producer, consumer, {
|
|
21
|
-
quotaOfEachTask:2,
|
|
22
|
-
numberOfWorkers: 6
|
|
23
|
-
});
|