multi-tasks 2.0.9 → 2.1.0

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 CHANGED
@@ -14,8 +14,7 @@ How to use:
14
14
  let multiTasks = require('multi-tasks').multiTasks;
15
15
 
16
16
 
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.
17
+ //Step1, create your tasks that need to be executed simultaneously as an array.
19
18
  let alltasks = [];
20
19
  for(let i=0;i<50;i++){
21
20
  alltasks.push({
@@ -26,9 +25,12 @@ for(let i=0;i<50;i++){
26
25
 
27
26
  //Step2, provide a function to process a certain sub-task and return the result data
28
27
  let processTask = (task, helper)=>{
29
- let {taskCount} = task;
28
+ let {taskCount} = task;//get your task data
29
+
30
+ //Run your processing logic here...
30
31
 
31
- return 'a result which is not a promise';
32
+ //then return the result as a plain javascript object or an async promise
33
+ return 'result data';
32
34
  };
33
35
 
34
36
  //Step3, run!
@@ -109,6 +111,7 @@ let processTask = (task, helper)=>{
109
111
 
110
112
  Changelog:
111
113
 
114
+ - 2.1.0 Add a new output directory "log" where you can view the process time of each subtask
112
115
  - 2.0.9 Update readme examples
113
116
  - 2.0.8 Update readme examples
114
117
  - 2.0.7 Update changelog
@@ -13,7 +13,7 @@ for(let i=0;i<50;i++){
13
13
  let processTask = (task, helper)=>{
14
14
  let {taskCount} = task;
15
15
 
16
- return 'a result which is not a promise';
16
+ return 'result data';
17
17
  };
18
18
 
19
19
  //Step2.1, or return a promise
@@ -76,10 +76,10 @@ let processTask = (task, helper)=>{
76
76
 
77
77
  //Step3, run!
78
78
  multiTasks.start({
79
- tasks: alltasks,
79
+ initialTasks: 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
82
- taskId: 'my-task',
82
+ taskId: 'my-readme-task',
83
83
  numberOfWorkers: 3, //Assign how many workers are working in parallel
84
84
  //autoCloseAfterCompletion: true, //if you have dynamically generated new tasks, put this as false
85
85
  onFinish: (report)=>{
@@ -44,7 +44,7 @@ multiTasks({
44
44
  initialTasks: 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
- taskId: 'my-task',
47
+ taskId: 'my-task' + Math.random(),
48
48
  numberOfWorkers: 3, //Assign how many workers are working in parallel
49
49
  //autoCloseAfterCompletion: true,
50
50
  onFinish: (report)=>{
@@ -0,0 +1,53 @@
1
+ import {multiTasks} from '../../index.js';
2
+
3
+ //Step1, If you have tasks that need to be executed simultaneously, please provide them as an array, multi-tasks will automatically split them and execute.
4
+ let alltasks = [];
5
+ for(let i=0;i<50;i++){
6
+ let task_props = {
7
+ index: i,
8
+ name: `task-${i}`,
9
+ description: `This prop is for a subtask`
10
+ };
11
+ alltasks.push(task_props);
12
+ }
13
+
14
+ //Step2, Provide a process function to handle a certain sub-task and return the result data
15
+ let processTask = (task, helper)=>{
16
+ //console.log('this is the subtask data you created above:', task);
17
+ let {taskCount} = task;
18
+
19
+ console.log(taskCount)
20
+
21
+
22
+ //This is the demo of exceptions/errors, they will be captured and saved in the results/errors folder
23
+ if(taskCount===3) throw 'exception';
24
+ if(taskCount===4) return Promise.reject({err:'a test error'});
25
+ if(taskCount===5) aaa = bbb;
26
+
27
+ if(taskCount===6) return 'a result which is not a promise'; //Return a non-promise result is also OK
28
+
29
+ //by default, you should return a promise, all returned data can be found in the results/succ folder
30
+ return new Promise((resolve, reject)=>{
31
+ setTimeout(()=>{
32
+ if(taskCount % 2 === 0)helper.createNewTasks({//
33
+ msg:'a new task'
34
+ });
35
+ taskCount === 2 ? reject('a rejected error') : resolve({
36
+ message: 'this is a result from a demo, random data=' + Math.random()
37
+ });
38
+ }, 10 * Math.random())
39
+ })
40
+ }
41
+
42
+ //Step3, run!
43
+ multiTasks({
44
+ initialTasks: alltasks,
45
+ processTask,
46
+ taskRootFolder: `../examples-tmp-data/example0`, //a directory to store progress and results files, you can check the progress here
47
+ taskId: 'my-task',
48
+ numberOfWorkers: 3, //Assign how many workers are working in parallel
49
+ //autoCloseAfterCompletion: true,
50
+ onFinish: (report)=>{
51
+ console.log('finish callback', report);
52
+ }
53
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multi-tasks",
3
- "version": "2.0.9",
3
+ "version": "2.1.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -35,7 +35,7 @@ let processTask = (task, helper)=>{
35
35
  taskCount === 2 ? reject('a rejected error') : resolve({
36
36
  message: 'this is a result from a demo, random data=' + Math.random()
37
37
  });
38
- }, 10 * Math.random())
38
+ }, 500 * Math.random())
39
39
  })
40
40
  }
41
41
 
@@ -1,4 +1,5 @@
1
1
  #!/bin/bash
2
+ rm -rf ./tmp
2
3
  node step1_start_and_crash
3
4
  sleep 3
4
5
  node step2_resume
@@ -156,9 +156,12 @@ function subWorker(){
156
156
  let sendMsg = (msg)=>{
157
157
  worker.send(msg);
158
158
  };
159
- runTask(config, subTask, sendMsg).then((report)=>{
160
- let endTimestamp = new Date()*1;
161
- let cost = startTimestamp - endTimestamp;
159
+ let subTaskLog = {
160
+ taskCount,
161
+ startTimestamp
162
+ };
163
+ runTask(config, subTask, subTaskLog, sendMsg).then((tasklog)=>{
164
+ let {cost, startTimestamp, endTimestamp} = tasklog;
162
165
 
163
166
  console.log(`[Task Finished] "${config.masterTaskId}"."${subTask.subid}".`, getDateTimeTxt(), `cost=${cost}ms`)
164
167
  }).then(()=>{
@@ -173,7 +176,7 @@ function subWorker(){
173
176
  worker.send(MSG_REQUEST_NEW_TASK);//request new task
174
177
 
175
178
  };
176
- function runTask(config, subTask, sendMsg){
179
+ function runTask(config, subTask, subTaskLog, sendMsg){
177
180
  return new Promise((resolve)=>{
178
181
  let resultPromise = Promise.resolve({});
179
182
  let resultData;
@@ -185,6 +188,7 @@ function runTask(config, subTask, sendMsg){
185
188
  params
186
189
  });
187
190
  };
191
+ TaskMgr.saveTaskLog(subTask.subid, subTaskLog);
188
192
  try{
189
193
  resultPromise = USER_CONFIG.processTask(subTask, helper);//rewrite this method in subclass
190
194
  }catch(e){
@@ -198,11 +202,24 @@ function runTask(config, subTask, sendMsg){
198
202
  if(typeof ex !== 'string') ex = ex.toString();
199
203
  errors.push({ex});
200
204
  }).finally(()=>{
205
+ let {startTimestamp} = subTaskLog;
206
+ let endTimestamp = new Date()*1;
207
+ let cost = endTimestamp - startTimestamp;
208
+ subTaskLog = {
209
+ ...subTaskLog,
210
+ endTimestamp,
211
+ cost
212
+ };
201
213
  let hasError = errors.length > 0;
202
- if(hasError)console.log('hasError=====', hasError, errors)
214
+ if(hasError)console.log('hasError=====', hasError, errors);
215
+ TaskMgr.saveTaskLog(subTask.subid, subTaskLog);
203
216
  TaskMgr.saveTaskResult(subTask.subid, hasError, hasError ? errors : resultData);
204
217
  TaskMgr.mvTask(subTask.subid, 'running',(hasError ? 'finished_with_errors':'finished'), (newPath)=>{
205
- resolve();
218
+ resolve({
219
+ startTimestamp,
220
+ endTimestamp,
221
+ cost
222
+ });
206
223
  });
207
224
  });
208
225
  });
@@ -43,19 +43,21 @@ const TaskMgr = {
43
43
  };
44
44
  //let taskfolder = pathutil.parse(__filename).dir;
45
45
  //let taskFolder = pathutil.resolve(taskfolder, `./tasks/${masterTaskId}`);
46
- progressRootFolder = pathutil.resolve(taskFolder, './progress');
47
- resultsRootFolder = pathutil.resolve(taskFolder, './results');
46
+ const progressRootFolder = pathutil.resolve(taskFolder, './progress');
47
+ const resultsRootFolder = pathutil.resolve(taskFolder, './results');
48
+ const logsRootFolder = pathutil.resolve(taskFolder, './logs');
48
49
 
49
- taskFolderNew = pathutil.resolve(progressRootFolder, './new');
50
- taskFolderRunning = pathutil.resolve(progressRootFolder, './running');
51
- taskFolderFinished = pathutil.resolve(progressRootFolder, './finished');
52
- taskFolderFailed= pathutil.resolve(progressRootFolder, './finished_with_errors');
50
+ const taskFolderNew = pathutil.resolve(progressRootFolder, './new');
51
+ const taskFolderRunning = pathutil.resolve(progressRootFolder, './running');
52
+ const taskFolderFinished = pathutil.resolve(progressRootFolder, './finished');
53
+ const taskFolderFailed= pathutil.resolve(progressRootFolder, './finished_with_errors');
53
54
 
54
- taskFolderResult = pathutil.resolve(resultsRootFolder, './succ');
55
- taskFolderResultFailed = pathutil.resolve(resultsRootFolder, './errors');
55
+ const taskFolderResult = pathutil.resolve(resultsRootFolder, './succ');
56
+ const taskFolderResultFailed = pathutil.resolve(resultsRootFolder, './errors');
56
57
  //let mainRptFolder = pathutil.resolve(taskfolder, './report');
57
58
 
58
59
  //makeDir.sync(mainRptFolder);
60
+ makeDir.sync(logsRootFolder);
59
61
  makeDir.sync(taskFolderNew);
60
62
  makeDir.sync(taskFolderRunning);
61
63
  makeDir.sync(taskFolderFinished);
@@ -68,6 +70,7 @@ const TaskMgr = {
68
70
  taskFolder,
69
71
  progressRootFolder,
70
72
  resultsRootFolder,
73
+ logsRootFolder,
71
74
 
72
75
  taskFolderNew,
73
76
  taskFolderRunning,
@@ -208,6 +211,19 @@ const TaskMgr = {
208
211
  fcontent = JSON.stringify(data);
209
212
  };
210
213
  fs.writeFileSync(fpath, fcontent);
214
+ },
215
+ saveTaskLog:(subid, log)=>{
216
+ let {logsRootFolder} = main_config;
217
+ let folder = logsRootFolder;
218
+ let fpath = pathutil.resolve(folder, `${subid}.json`);
219
+ let fcontent;
220
+ log.subid = subid;
221
+ if(typeof log === 'undefined') {
222
+ fcontent = '';
223
+ }else{
224
+ fcontent = JSON.stringify(log);
225
+ };
226
+ fs.writeFileSync(fpath, fcontent);
211
227
  }
212
228
  };
213
229
  module.exports = TaskMgr;