react 0.3.0 → 0.3.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 +148 -97
- package/doc/alternate-dsls.md +103 -0
- package/examples/chain-events1.js +26 -5
- package/examples/default-events1.js +32 -5
- package/examples/default-log-events.js +43 -0
- package/examples/fstr-events1.js +1 -15
- package/lib/base-task.js +7 -6
- package/lib/core.js +20 -13
- package/lib/event-manager.js +15 -13
- package/lib/finalcb-first-task.js +14 -11
- package/lib/finalcb-task.js +15 -11
- package/lib/log-events.js +71 -0
- package/lib/task.js +10 -5
- package/lib/track-tasks.js +117 -0
- package/package.json +1 -1
- package/promise-resolve.js +4 -4
- package/test/core.test.js +45 -56
- package/test/dsl/chain.test.js +1 -0
- package/test/dsl/pcode.test.js +22 -30
- package/test/module-use.test.js +11 -9
|
@@ -1,22 +1,49 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/*jshint white: false */
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
Default DSL, showing use of events
|
|
6
|
+
*/
|
|
7
|
+
|
|
4
8
|
var react = require('../'); // require('react');
|
|
9
|
+
require('../lib/track-tasks'); // require('react/lib/track-tasks'); // turn on tracking
|
|
5
10
|
|
|
6
11
|
//output events as tasks start and complete
|
|
7
|
-
react.events.on('
|
|
12
|
+
react.events.on('flow.*', function (obj) {
|
|
13
|
+
/*jshint validthis: true */
|
|
8
14
|
var time = new Date();
|
|
9
15
|
time.setTime(obj.time);
|
|
16
|
+
var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
|
|
10
17
|
var eventTimeStr = time.toISOString();
|
|
18
|
+
if (this.event === 'flow.complete') {
|
|
19
|
+
var env = obj;
|
|
20
|
+
console.error('%s: %s \tmsecs:(%s) \n\targs:(%s) \n\tresults:(%s)\n',
|
|
21
|
+
this.event, env.name, env.elapsedTime, argsNoCb, env.results);
|
|
22
|
+
} else {
|
|
23
|
+
var name = obj.name;
|
|
24
|
+
var args = obj.args;
|
|
25
|
+
console.error('%s: %s \n\targs:(%s)\n', this.event, name, argsNoCb);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
react.events.on('task.*', function (obj) {
|
|
30
|
+
/*jshint validthis: true */
|
|
31
|
+
var time = new Date();
|
|
32
|
+
time.setTime(obj.time);
|
|
11
33
|
var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
|
|
12
|
-
|
|
34
|
+
var eventTimeStr = time.toISOString();
|
|
35
|
+
if (this.event === 'task.complete') {
|
|
36
|
+
var task = obj;
|
|
13
37
|
console.error('%s: %s \tmsecs:(%s) \n\targs:(%s) \n\tresults:(%s)\n',
|
|
14
|
-
|
|
38
|
+
this.event, task.name, task.elapsedTime, argsNoCb, task.results);
|
|
15
39
|
} else {
|
|
16
|
-
|
|
40
|
+
var name = obj.name;
|
|
41
|
+
var args = obj.args;
|
|
42
|
+
console.error('%s: %s \n\targs:(%s)\n', this.event, name, argsNoCb);
|
|
17
43
|
}
|
|
18
44
|
});
|
|
19
|
-
|
|
45
|
+
|
|
46
|
+
|
|
20
47
|
|
|
21
48
|
function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
|
|
22
49
|
function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/*jshint white: false */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
Default DSL, showing use of events
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
var react = require('../'); // require('react');
|
|
9
|
+
require('../lib/log-events').logEvents(react); // require('react/lib/log-events').logEvents(react); // turn on logging
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
|
|
13
|
+
function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
|
|
14
|
+
function markdown(filedata) { return 'html'+filedata; }
|
|
15
|
+
function prepareDirectory(outDirname, cb){ setTimeout(cb, 200, null, 'dircreated-'+outDirname); }
|
|
16
|
+
function writeOutput(html, user, cb){ setTimeout(cb, 300, null, html+'_bytesWritten'); }
|
|
17
|
+
function loadEmailTemplate(cb) { setTimeout(cb, 50, null, 'emailmd'); }
|
|
18
|
+
function customizeEmail(user, emailHtml) { return 'cust-'+user+emailHtml; }
|
|
19
|
+
function deliverEmail(custEmailHtml, cb) { setTimeout(cb, 100, null, 'delivered-'+custEmailHtml); }
|
|
20
|
+
|
|
21
|
+
function useHtml(err, html, user, bytesWritten) {
|
|
22
|
+
if (err) {
|
|
23
|
+
console.log('***Error: %s', err);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log('final result: %s, user: %s, written:%s', html, user, bytesWritten);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var loadAndSave = react('loadAndSave', 'filename, uid, outDirname, cb -> err, html, user, bytesWritten', // name, in/out params
|
|
30
|
+
loadUser, 'uid, cb -> err, user', // calling async fn loadUser with uid, callback is called with err and user
|
|
31
|
+
loadFile, 'filename, cb -> err, filedata',
|
|
32
|
+
markdown, 'filedata -> html', // using a sync function
|
|
33
|
+
prepareDirectory, 'outDirname, cb -> err, dircreated',
|
|
34
|
+
writeOutput, 'html, user, cb -> err, bytesWritten', { after: prepareDirectory }, // only after prepareDirectory done
|
|
35
|
+
loadEmailTemplate, 'cb -> err, emailmd',
|
|
36
|
+
markdown, 'emailmd -> emailHtml', // using a sync function
|
|
37
|
+
customizeEmail, 'user, emailHtml -> custEmailHtml', // sync fn
|
|
38
|
+
deliverEmail, 'custEmailHtml, cb -> err, deliveredEmail', { after: writeOutput } // only after writeOutput is done
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
loadAndSave('file.md', 100, '/tmp/foo', useHtml); // executing the flow
|
|
42
|
+
|
|
43
|
+
|
package/examples/fstr-events1.js
CHANGED
|
@@ -2,21 +2,7 @@
|
|
|
2
2
|
/*jshint white: false */
|
|
3
3
|
|
|
4
4
|
var fstr = require('../dsl/fstr'); // require('react/dsl/fstr');
|
|
5
|
-
|
|
6
|
-
//output events as tasks start and complete
|
|
7
|
-
fstr.events.on('task.*', function (obj) {
|
|
8
|
-
var time = new Date();
|
|
9
|
-
time.setTime(obj.time);
|
|
10
|
-
var eventTimeStr = time.toISOString();
|
|
11
|
-
var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
|
|
12
|
-
if (obj.event === 'task.complete') {
|
|
13
|
-
console.error('%s: %s \tmsecs:(%s) \n\targs:(%s) \n\tresults:(%s)\n',
|
|
14
|
-
obj.event, obj.name, obj.elapsedTime, argsNoCb, obj.results);
|
|
15
|
-
} else {
|
|
16
|
-
console.error('%s: %s \n\targs:(%s)\n', obj.event, obj.name, argsNoCb);
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
5
|
+
require('../lib/log-events').logEvents(fstr); // require('react/lib/log-events').logEvents(react);
|
|
20
6
|
|
|
21
7
|
function loadUser(uid, cb){ setTimeout(cb, 100, null, "User"+uid); }
|
|
22
8
|
function loadFile(filename, cb){ setTimeout(cb, 100, null, 'Filedata'+filename); }
|
package/lib/base-task.js
CHANGED
|
@@ -19,17 +19,18 @@ BaseTask.prototype.isComplete = function () {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
BaseTask.prototype.start = function (args) { // mark task as started with args and note time
|
|
22
|
+
/*jshint validthis: true */
|
|
22
23
|
this.args = args;
|
|
23
|
-
this.
|
|
24
|
-
|
|
24
|
+
this.env.currentTask = this;
|
|
25
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_TASK_START, this);
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
BaseTask.prototype.complete = function (args) { //args that were used are available
|
|
28
|
-
|
|
29
|
-
this.endTime = Date.now();
|
|
30
|
-
this.elapsedTime = this.endTime - this.startTime;
|
|
31
|
-
if (this.flowEmitter) this.flowEmitter.emitObject(EventManager.TYPES.TASK_COMPLETE, this);
|
|
29
|
+
/*jshint validthis: true */
|
|
32
30
|
this.status = STATUS.COMPLETE;
|
|
31
|
+
this.results = args;
|
|
32
|
+
this.env.currentTask = this;
|
|
33
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_TASK_COMPLETE, this);
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
BaseTask.prototype.functionExists = function (vCon) {
|
package/lib/core.js
CHANGED
|
@@ -76,32 +76,39 @@ function reactFactory() {
|
|
|
76
76
|
|
|
77
77
|
function exec(arg1, arg2, argN, cb) { // called to execute the flow
|
|
78
78
|
/*jshint validthis: true */
|
|
79
|
-
var
|
|
79
|
+
var args = Array.prototype.slice.call(arguments);
|
|
80
|
+
var env = {
|
|
81
|
+
execId: idGenerator.createUniqueId(),
|
|
82
|
+
args: args,
|
|
83
|
+
ast: ast,
|
|
84
|
+
flowEmitter: flowEmitter
|
|
85
|
+
};
|
|
86
|
+
env.name = ast.name || env.execId;
|
|
87
|
+
flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_START, env); // hook
|
|
88
|
+
var parsedInput = inputParser(args, ast);
|
|
80
89
|
var vCon = VContext.create(parsedInput.args, ast.inParams, ast.locals, this); // create var ctx with in args & locals
|
|
81
90
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
reactEmitter.emit(EventManager.TYPES.EXEC_TASKS_PRECREATE, taskEnv); // hook
|
|
91
|
+
env.parsedInput = parsedInput;
|
|
92
|
+
env.options = mergeOptions(parsedInput.options);
|
|
93
|
+
env.vCon = vCon;
|
|
94
|
+
env.taskDefs = ast.tasks.slice(); // create copy
|
|
95
|
+
env.outTaskDef = Object.create(ast.outTask); // create copy
|
|
96
|
+
reactEmitter.emit(EventManager.TYPES.EXEC_TASKS_PRECREATE, env); // hook
|
|
90
97
|
|
|
91
|
-
var tasks =
|
|
98
|
+
var tasks = env.taskDefs.map(tskutil.create);
|
|
92
99
|
var tasksByName = tskutil.nameTasks(tasks); // map names to working tasks
|
|
93
|
-
var outTask = tskutil.createOutTask(
|
|
100
|
+
var outTask = tskutil.createOutTask(env.outTaskDef, parsedInput.cb, tasks, vCon, env.options, env);
|
|
94
101
|
var handleError = tskutil.createErrorHandler(vCon, outTask);
|
|
95
102
|
|
|
96
103
|
function contExec() {
|
|
97
104
|
if (!outTask.f) { return; } //stop execution, we already hit an error, f was cleared
|
|
98
105
|
if (outTask.isReady()) return outTask.exec(); // all tasks done, exec cb, return
|
|
99
|
-
tskutil.findReadyAndExec(vCon, tasks, tasksByName, handleError, contExec); //exec tasks that ready to run
|
|
106
|
+
tskutil.findReadyAndExec(vCon, tasks, tasksByName, handleError, contExec, env); //exec tasks that ready to run
|
|
100
107
|
}
|
|
101
108
|
|
|
102
109
|
tasks.forEach(function (t) {
|
|
103
110
|
t.id = idGenerator.createUniqueId();
|
|
104
|
-
t.
|
|
111
|
+
t.env = env;
|
|
105
112
|
if (t.prepare) t.prepare(handleError, vCon, contExec, flowEmitter);
|
|
106
113
|
}); // create callbacks
|
|
107
114
|
contExec(); // start things off
|
package/lib/event-manager.js
CHANGED
|
@@ -10,13 +10,23 @@ var EVENT_EMITTER2_CONFIG = {
|
|
|
10
10
|
|
|
11
11
|
var TYPES = {
|
|
12
12
|
// Flow monitoring events and their params
|
|
13
|
+
FLOW_BEGIN: 'flow.begin', // env
|
|
13
14
|
TASK_BEGIN: 'task.begin', // task
|
|
14
15
|
TASK_COMPLETE: 'task.complete', // task
|
|
16
|
+
TASK_ERRORED: 'task.errored', // task
|
|
17
|
+
FLOW_COMPLETE: 'flow.complete', // env
|
|
18
|
+
FLOW_ERRORED: 'flow.errored', // env
|
|
15
19
|
|
|
16
20
|
// Internal Hooks
|
|
21
|
+
EXEC_FLOW_START: 'exec.flow.start', // env
|
|
17
22
|
EXEC_INPUT_PREPROCESS: 'exec.input.preprocess', // parsedInput
|
|
18
|
-
EXEC_TASKS_PRECREATE: 'exec.tasks.precreate',
|
|
19
|
-
EXEC_OUTTASK_CREATE: 'exec.outTask.create' // outTaskOptions
|
|
23
|
+
EXEC_TASKS_PRECREATE: 'exec.tasks.precreate', // env
|
|
24
|
+
EXEC_OUTTASK_CREATE: 'exec.outTask.create', // outTaskOptions
|
|
25
|
+
EXEC_TASK_START: 'exec.task.start', // task
|
|
26
|
+
EXEC_TASK_COMPLETE: 'exec.task.complete', // task
|
|
27
|
+
EXEC_TASK_ERRORED: 'exec.task.errored', // task
|
|
28
|
+
EXEC_FLOW_COMPLETE: 'exec.flow.complete', // env
|
|
29
|
+
EXEC_FLOW_ERRORED: 'exec.flow.errored' // env
|
|
20
30
|
};
|
|
21
31
|
|
|
22
32
|
/**
|
|
@@ -52,18 +62,10 @@ EventManager.prototype.emit = function (event, arg1, arg2, argN) {
|
|
|
52
62
|
if (this.parent && this.parent.isEnabled()) this.parent.emit.apply(this.parent, arguments);
|
|
53
63
|
};
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Copies object and adds standard fields:
|
|
58
|
-
event: event type
|
|
59
|
-
time: current time
|
|
60
|
-
*/
|
|
61
|
-
EventManager.prototype.emitObject = function (event, object) {
|
|
62
|
-
var evObj = Object.create(object); // create inherited copy version so origin is untouched
|
|
63
|
-
evObj.event = event; // augment with the event type
|
|
64
|
-
evObj.time = Date.now(); // augument with the time of the event
|
|
65
|
-
this.emit(event, evObj);
|
|
65
|
+
EventManager.prototype.removeListener = function (event, listener) {
|
|
66
|
+
if (this.emitter) this.emitter.removeListener.apply(this.emitter, arguments);
|
|
66
67
|
};
|
|
67
68
|
|
|
69
|
+
|
|
68
70
|
module.exports = EventManager;
|
|
69
71
|
module.exports.global = EventManager.create(); // create one top level emitter
|
|
@@ -5,23 +5,22 @@ var util = require('util');
|
|
|
5
5
|
|
|
6
6
|
var STATUS = require('./status.js');
|
|
7
7
|
var VContext = require('./vcon.js');
|
|
8
|
+
var EventManager = require('./event-manager.js');
|
|
8
9
|
|
|
9
10
|
var OUTTASK_A_REQ = 'ast.outTask.a should be an array of string param names';
|
|
10
11
|
|
|
11
12
|
function FinalCbFirstSuccTask(outTaskOptions) {
|
|
12
13
|
var taskDef = outTaskOptions.taskDef;
|
|
13
|
-
|
|
14
|
-
var tasks = outTaskOptions.tasks;
|
|
15
|
-
var vCon = outTaskOptions.vCon;
|
|
16
|
-
var execOptions = outTaskOptions.execOptions;
|
|
17
|
-
var retValue = outTaskOptions.retValue;
|
|
18
|
-
if (typeof(cbFunc) !== 'function') throw new Error('callback is not a function');
|
|
14
|
+
if (typeof(outTaskOptions.cbFunc) !== 'function') throw new Error('callback is not a function');
|
|
19
15
|
var self = this;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
16
|
+
for (var k in taskDef) {
|
|
17
|
+
if (true) self[k] = taskDef[k]; // if to make jshint happy
|
|
18
|
+
}
|
|
19
|
+
this.f = outTaskOptions.cbFunc;
|
|
20
|
+
this.tasks = outTaskOptions.tasks;
|
|
21
|
+
this.vCon = outTaskOptions.vCon;
|
|
22
|
+
this.retValue = outTaskOptions.retValue;
|
|
23
|
+
this.env = outTaskOptions.env;
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
function format_error(errmsg, obj) {
|
|
@@ -49,11 +48,15 @@ FinalCbFirstSuccTask.prototype.isReady = function () {
|
|
|
49
48
|
FinalCbFirstSuccTask.prototype.exec = function (err) {
|
|
50
49
|
if (!this.f) return; //must have already been called
|
|
51
50
|
if (err) {
|
|
51
|
+
this.env.error = err;
|
|
52
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_ERRORED, this.env);
|
|
52
53
|
this.f.call(null, err); //call the final callback with the first error hit
|
|
53
54
|
} else { // no error, call with args
|
|
54
55
|
var vCon = this.vCon;
|
|
55
56
|
var finalArgs = this.a.map(function (k) { return vCon.getVar(k); });
|
|
56
57
|
finalArgs.unshift(null); //unshift err=null to front
|
|
58
|
+
this.env.results = finalArgs;
|
|
59
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_COMPLETE, this.env);
|
|
57
60
|
this.f.apply(null, finalArgs);
|
|
58
61
|
}
|
|
59
62
|
this.f = null; // prevent multiple calls
|
package/lib/finalcb-task.js
CHANGED
|
@@ -4,23 +4,23 @@ var sprintf = require('sprintf').sprintf;
|
|
|
4
4
|
var util = require('util');
|
|
5
5
|
|
|
6
6
|
var STATUS = require('./status.js');
|
|
7
|
+
var EventManager = require('./event-manager.js');
|
|
7
8
|
|
|
8
9
|
var OUTTASK_A_REQ = 'ast.outTask.a should be an array of string param names';
|
|
9
10
|
|
|
10
11
|
function FinalCbTask(outTaskOptions) {
|
|
11
12
|
var taskDef = outTaskOptions.taskDef;
|
|
12
|
-
|
|
13
|
-
var tasks = outTaskOptions.tasks;
|
|
14
|
-
var vCon = outTaskOptions.vCon;
|
|
15
|
-
var execOptions = outTaskOptions.execOptions;
|
|
16
|
-
var retValue = outTaskOptions.retValue;
|
|
17
|
-
if (typeof(cbFunc) !== 'function') throw new Error('callback is not a function');
|
|
13
|
+
if (typeof(outTaskOptions.cbFunc) !== 'function') throw new Error('callback is not a function');
|
|
18
14
|
var self = this;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
15
|
+
for (var k in taskDef) {
|
|
16
|
+
if (true) self[k] = taskDef[k]; // if to make jshint happy
|
|
17
|
+
}
|
|
18
|
+
this.f = outTaskOptions.cbFunc;
|
|
19
|
+
this.tasks = outTaskOptions.tasks;
|
|
20
|
+
this.vCon = outTaskOptions.vCon;
|
|
21
|
+
this.retValue = outTaskOptions.retValue;
|
|
22
|
+
this.execOptions = outTaskOptions.execOptions;
|
|
23
|
+
this.env = outTaskOptions.env;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
function format_error(errmsg, obj) {
|
|
@@ -44,11 +44,15 @@ FinalCbTask.prototype.isReady = function () {
|
|
|
44
44
|
FinalCbTask.prototype.exec = function (err) {
|
|
45
45
|
if (!this.f) return; //must have already been called
|
|
46
46
|
if (err) {
|
|
47
|
+
this.env.error = err;
|
|
48
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_ERRORED, this.env);
|
|
47
49
|
this.f.call(null, err); //call the final callback with the first error hit
|
|
48
50
|
} else { // no error, call with args
|
|
49
51
|
var vCon = this.vCon;
|
|
50
52
|
var finalArgs = this.a.map(function (k) { return vCon.getVar(k); });
|
|
51
53
|
finalArgs.unshift(null); //unshift err=null to front
|
|
54
|
+
this.env.results = finalArgs;
|
|
55
|
+
this.env.flowEmitter.emit(EventManager.TYPES.EXEC_FLOW_COMPLETE, this.env);
|
|
52
56
|
this.f.apply(null, finalArgs);
|
|
53
57
|
}
|
|
54
58
|
this.f = null; // prevent multiple calls
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Log events to console.error
|
|
5
|
+
|
|
6
|
+
@example
|
|
7
|
+
var react = require('react');
|
|
8
|
+
require('react/lib/log-events').logEvent(react);
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
var react = require('../lib/track-tasks'); // require('react/lib/track-tasks'); // turn on tracking
|
|
12
|
+
|
|
13
|
+
var ALL_FLOW_EVENTS = 'flow.*';
|
|
14
|
+
var ALL_TASK_EVENTS = 'task.*';
|
|
15
|
+
|
|
16
|
+
function flowLog(obj) {
|
|
17
|
+
/*jshint validthis: true */
|
|
18
|
+
var time = new Date();
|
|
19
|
+
time.setTime(obj.time);
|
|
20
|
+
var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
|
|
21
|
+
var eventTimeStr = time.toISOString();
|
|
22
|
+
if (this.event === 'flow.complete') {
|
|
23
|
+
var env = obj;
|
|
24
|
+
console.error('%s: %s \tmsecs:(%s) \n\targs:(%s) \n\tresults:(%s)\n',
|
|
25
|
+
this.event, env.name, env.elapsedTime, argsNoCb, env.results);
|
|
26
|
+
} else {
|
|
27
|
+
var name = obj.name;
|
|
28
|
+
var args = obj.args;
|
|
29
|
+
console.error('%s: %s \n\targs:(%s)\n', this.event, name, argsNoCb);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function taskLog(obj) {
|
|
34
|
+
/*jshint validthis: true */
|
|
35
|
+
var time = new Date();
|
|
36
|
+
time.setTime(obj.time);
|
|
37
|
+
var argsNoCb = obj.args.filter(function (a) { return (typeof(a) !== 'function'); });
|
|
38
|
+
var eventTimeStr = time.toISOString();
|
|
39
|
+
if (this.event === 'task.complete') {
|
|
40
|
+
var task = obj;
|
|
41
|
+
console.error('%s: %s \tmsecs:(%s) \n\targs:(%s) \n\tresults:(%s)\n',
|
|
42
|
+
this.event, task.name, task.elapsedTime, argsNoCb, task.results);
|
|
43
|
+
} else {
|
|
44
|
+
var name = obj.name;
|
|
45
|
+
var args = obj.args;
|
|
46
|
+
console.error('%s: %s \n\targs:(%s)\n', this.event, name, argsNoCb);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
Log flow and task events for a flowFn or all of react.
|
|
53
|
+
If called multiple times, remove previous listener (if any) before
|
|
54
|
+
adding.
|
|
55
|
+
|
|
56
|
+
@example
|
|
57
|
+
var react = require('react');
|
|
58
|
+
require('react/lib/log-events').logEvents(flowFn); // pass flowFn or react
|
|
59
|
+
|
|
60
|
+
@param flowFn Flow function or global react object
|
|
61
|
+
*/
|
|
62
|
+
function logEvents(flowFn) {
|
|
63
|
+
//output events as tasks start and complete
|
|
64
|
+
flowFn.events.removeListener(ALL_FLOW_EVENTS, flowLog);
|
|
65
|
+
flowFn.events.on(ALL_FLOW_EVENTS, flowLog);
|
|
66
|
+
flowFn.events.removeListener(ALL_TASK_EVENTS, taskLog);
|
|
67
|
+
flowFn.events.on(ALL_TASK_EVENTS, taskLog);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = react;
|
|
71
|
+
module.exports.logEvents = logEvents;
|
package/lib/task.js
CHANGED
|
@@ -163,7 +163,7 @@ function create(taskDef) {
|
|
|
163
163
|
return new TaskConstructor(taskDef);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
function createOutTask(taskDef, cbFunc, tasks, vCon, execOptions) {
|
|
166
|
+
function createOutTask(taskDef, cbFunc, tasks, vCon, execOptions, env) {
|
|
167
167
|
setMissingOutTaskType(taskDef);
|
|
168
168
|
var outTaskOptions = {
|
|
169
169
|
taskDef: taskDef,
|
|
@@ -171,6 +171,7 @@ function createOutTask(taskDef, cbFunc, tasks, vCon, execOptions) {
|
|
|
171
171
|
tasks: tasks,
|
|
172
172
|
vCon: vCon,
|
|
173
173
|
execOptions: execOptions,
|
|
174
|
+
env: env,
|
|
174
175
|
TaskConstructor: OUT_TASK_TYPES[taskDef.type]
|
|
175
176
|
};
|
|
176
177
|
EventManager.global.emit(EventManager.TYPES.EXEC_OUTTASK_CREATE, outTaskOptions); // hook
|
|
@@ -181,6 +182,9 @@ function createOutTask(taskDef, cbFunc, tasks, vCon, execOptions) {
|
|
|
181
182
|
function createErrorHandler(vCon, outTask) {
|
|
182
183
|
return function handleError(task, err) {
|
|
183
184
|
task.status = STATUS.ERRORED;
|
|
185
|
+
task.error = err;
|
|
186
|
+
outTask.env.currentTask = task;
|
|
187
|
+
outTask.env.flowEmitter.emit(EventManager.TYPES.EXEC_TASK_ERRORED, task);
|
|
184
188
|
var errWithMeta = error.augmentError(err, {task: task, vcon: vCon});
|
|
185
189
|
outTask.exec(errWithMeta); //call the final callback with the first error hit
|
|
186
190
|
};
|
|
@@ -202,7 +206,7 @@ function execTasks(tasksReady, vCon, handleError, contExec) {
|
|
|
202
206
|
case everything is fine. If no tasks are running then
|
|
203
207
|
call handleError since this will never complete.
|
|
204
208
|
*/
|
|
205
|
-
function checkIfTasksRunning(vCon, tasks, handleError) {
|
|
209
|
+
function checkIfTasksRunning(vCon, tasks, handleError, env) {
|
|
206
210
|
var tasksRunning = tasks.filter(function (t) {
|
|
207
211
|
return (t.status === STATUS.RUNNING || t.status === STATUS.READY);
|
|
208
212
|
});
|
|
@@ -210,13 +214,14 @@ function checkIfTasksRunning(vCon, tasks, handleError) {
|
|
|
210
214
|
var remainingTasks = tasks.filter(function (t) { return (!t.status); });
|
|
211
215
|
var remainingTNames = remainingTasks.map(function (t) { return t.name; });
|
|
212
216
|
var errMsg = sprintf(NO_TASKS_RUNNING_WONT_COMPLETE, remainingTNames.join(', '));
|
|
213
|
-
|
|
217
|
+
var emptyTask = { env: env };
|
|
218
|
+
handleError(emptyTask, new Error(errMsg));
|
|
214
219
|
}
|
|
215
220
|
}
|
|
216
221
|
|
|
217
|
-
function findReadyAndExec(vCon, tasks, tasksByName, handleError, contExec) {
|
|
222
|
+
function findReadyAndExec(vCon, tasks, tasksByName, handleError, contExec, env) {
|
|
218
223
|
var tasksReady = findTasksReady(vCon, tasks, tasksByName);
|
|
219
|
-
if (!tasksReady.length) checkIfTasksRunning(vCon, tasks, handleError); // no tasks to run, check if ok
|
|
224
|
+
if (!tasksReady.length) checkIfTasksRunning(vCon, tasks, handleError, env); // no tasks to run, check if ok
|
|
220
225
|
execTasks(tasksReady, vCon, handleError, contExec);
|
|
221
226
|
}
|
|
222
227
|
|