@logicflow/engine 0.0.2 → 0.0.3
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/CHANGELOG.md +12 -0
- package/cjs/FlowModel.js +24 -38
- package/cjs/Scheduler.js +53 -54
- package/cjs/constant/constant.js +8 -8
- package/cjs/expression/browserVm.js +30 -22
- package/cjs/expression/nodeVm.js +1 -1
- package/cjs/index.js +34 -9
- package/cjs/nodes/BaseNode.js +10 -10
- package/cjs/recorder/index.js +41 -20
- package/cjs/util/ID.js +7 -3
- package/es/FlowModel.d.ts +11 -11
- package/es/FlowModel.js +24 -38
- package/es/Scheduler.d.ts +9 -9
- package/es/Scheduler.js +54 -55
- package/es/constant/constant.d.ts +1 -1
- package/es/constant/constant.js +7 -7
- package/es/expression/browserVm.d.ts +3 -1
- package/es/expression/browserVm.js +28 -22
- package/es/expression/nodeVm.js +1 -1
- package/es/index.d.ts +22 -11
- package/es/index.js +34 -9
- package/es/nodes/BaseNode.d.ts +19 -8
- package/es/nodes/BaseNode.js +11 -11
- package/es/recorder/index.d.ts +8 -4
- package/es/recorder/index.js +41 -20
- package/es/util/ID.d.ts +2 -1
- package/es/util/ID.js +6 -2
- package/lib/main.js +1 -1
- package/package.json +4 -1
package/cjs/recorder/index.js
CHANGED
|
@@ -38,13 +38,18 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
var storage_1 = require("../util/storage");
|
|
40
40
|
var LOGICFLOW_ENGINE_INSTANCES = 'LOGICFLOW_ENGINE_INSTANCES';
|
|
41
|
+
var MAX_RECORDER = 100;
|
|
41
42
|
var Recorder = /** @class */ (function () {
|
|
42
43
|
function Recorder() {
|
|
44
|
+
this.maxRecorder = MAX_RECORDER;
|
|
43
45
|
}
|
|
46
|
+
Recorder.prototype.setMaxRecorderNumber = function (maxRecorder) {
|
|
47
|
+
this.maxRecorder = maxRecorder;
|
|
48
|
+
};
|
|
44
49
|
/*
|
|
45
|
-
* @param {Object}
|
|
50
|
+
* @param {Object} action
|
|
46
51
|
* {
|
|
47
|
-
*
|
|
52
|
+
* actionId: '',
|
|
48
53
|
* nodeId: '',
|
|
49
54
|
* executionId: '',
|
|
50
55
|
* nodeType: '',
|
|
@@ -52,29 +57,34 @@ var Recorder = /** @class */ (function () {
|
|
|
52
57
|
* properties: {},
|
|
53
58
|
* }
|
|
54
59
|
*/
|
|
55
|
-
Recorder.prototype.
|
|
60
|
+
Recorder.prototype.addActionRecord = function (action) {
|
|
56
61
|
return __awaiter(this, void 0, void 0, function () {
|
|
57
|
-
var executionId,
|
|
62
|
+
var executionId, actionId, instanceData;
|
|
58
63
|
return __generator(this, function (_a) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
switch (_a.label) {
|
|
65
|
+
case 0:
|
|
66
|
+
executionId = action.executionId, actionId = action.actionId;
|
|
67
|
+
return [4 /*yield*/, this.getExecutionActions(executionId)];
|
|
68
|
+
case 1:
|
|
69
|
+
instanceData = _a.sent();
|
|
70
|
+
if (!instanceData) {
|
|
71
|
+
this.pushExecution(executionId);
|
|
72
|
+
}
|
|
73
|
+
this.pushActionToExecution(executionId, actionId);
|
|
74
|
+
storage_1.default.setItem(actionId, action);
|
|
75
|
+
return [2 /*return*/];
|
|
63
76
|
}
|
|
64
|
-
this.pushTaskToExecution(executionId, taskId);
|
|
65
|
-
storage_1.default.setItem(taskId, task);
|
|
66
|
-
return [2 /*return*/];
|
|
67
77
|
});
|
|
68
78
|
});
|
|
69
79
|
};
|
|
70
|
-
Recorder.prototype.
|
|
80
|
+
Recorder.prototype.getActionRecord = function (actionId) {
|
|
71
81
|
return __awaiter(this, void 0, void 0, function () {
|
|
72
82
|
return __generator(this, function (_a) {
|
|
73
|
-
return [2 /*return*/, storage_1.default.getItem(
|
|
83
|
+
return [2 /*return*/, storage_1.default.getItem(actionId)];
|
|
74
84
|
});
|
|
75
85
|
});
|
|
76
86
|
};
|
|
77
|
-
Recorder.prototype.
|
|
87
|
+
Recorder.prototype.getExecutionActions = function (executionId) {
|
|
78
88
|
return __awaiter(this, void 0, void 0, function () {
|
|
79
89
|
return __generator(this, function (_a) {
|
|
80
90
|
return [2 /*return*/, storage_1.default.getItem(executionId)];
|
|
@@ -86,21 +96,32 @@ var Recorder = /** @class */ (function () {
|
|
|
86
96
|
instance.forEach(function (executionId) {
|
|
87
97
|
storage_1.default.removeItem(executionId);
|
|
88
98
|
var instanceData = storage_1.default.getItem(executionId) || [];
|
|
89
|
-
instanceData.forEach(function (
|
|
90
|
-
storage_1.default.removeItem(
|
|
99
|
+
instanceData.forEach(function (actionId) {
|
|
100
|
+
storage_1.default.removeItem(actionId);
|
|
91
101
|
});
|
|
92
102
|
});
|
|
93
103
|
storage_1.default.removeItem(LOGICFLOW_ENGINE_INSTANCES);
|
|
94
104
|
};
|
|
95
105
|
Recorder.prototype.pushExecution = function (executionId) {
|
|
96
106
|
var instance = storage_1.default.getItem(LOGICFLOW_ENGINE_INSTANCES) || [];
|
|
107
|
+
if (instance.length >= this.maxRecorder) {
|
|
108
|
+
var removeItem = instance.shift();
|
|
109
|
+
this.popExecution(removeItem);
|
|
110
|
+
}
|
|
97
111
|
instance.push(executionId);
|
|
98
112
|
storage_1.default.setItem(LOGICFLOW_ENGINE_INSTANCES, instance);
|
|
99
113
|
};
|
|
100
|
-
Recorder.prototype.
|
|
101
|
-
var
|
|
102
|
-
|
|
103
|
-
|
|
114
|
+
Recorder.prototype.popExecution = function (executionId) {
|
|
115
|
+
var instanceData = storage_1.default.getItem(executionId) || [];
|
|
116
|
+
instanceData.forEach(function (actionId) {
|
|
117
|
+
storage_1.default.removeItem(actionId);
|
|
118
|
+
});
|
|
119
|
+
storage_1.default.removeItem(executionId);
|
|
120
|
+
};
|
|
121
|
+
Recorder.prototype.pushActionToExecution = function (executionId, actionId) {
|
|
122
|
+
var actions = storage_1.default.getItem(executionId) || [];
|
|
123
|
+
actions.push(actionId);
|
|
124
|
+
storage_1.default.setItem(executionId, actions);
|
|
104
125
|
};
|
|
105
126
|
return Recorder;
|
|
106
127
|
}());
|
package/cjs/util/ID.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.createEngineId = exports.createActionId = exports.createExecId = void 0;
|
|
4
4
|
var uuid_1 = require("uuid");
|
|
5
5
|
exports.createExecId = function () {
|
|
6
6
|
var uuid = uuid_1.v4();
|
|
7
7
|
return "exec-" + uuid;
|
|
8
8
|
};
|
|
9
|
-
exports.
|
|
9
|
+
exports.createActionId = function () {
|
|
10
10
|
var uuid = uuid_1.v4();
|
|
11
|
-
return "
|
|
11
|
+
return "action-" + uuid;
|
|
12
|
+
};
|
|
13
|
+
exports.createEngineId = function () {
|
|
14
|
+
var uuid = uuid_1.v4();
|
|
15
|
+
return "engine-" + uuid;
|
|
12
16
|
};
|
package/es/FlowModel.d.ts
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
import type { NodeConfig, NodeConstructor } from './nodes/BaseNode';
|
|
2
2
|
import type Recorder from './recorder';
|
|
3
3
|
import Scheduler from './Scheduler';
|
|
4
|
-
import type {
|
|
4
|
+
import type { ActionParam } from './types.d';
|
|
5
5
|
export declare type FlowResult = {
|
|
6
6
|
result?: Record<string, any>;
|
|
7
|
-
} &
|
|
8
|
-
export declare type
|
|
7
|
+
} & ActionParam;
|
|
8
|
+
export declare type ActionParams = {
|
|
9
9
|
executionId?: string;
|
|
10
|
-
|
|
10
|
+
actionId?: string;
|
|
11
11
|
nodeId?: string;
|
|
12
|
-
data?: Record<string, any>;
|
|
13
12
|
};
|
|
14
13
|
export declare type ExecParams = {
|
|
15
14
|
callback?: (result: FlowResult) => void;
|
|
16
15
|
onError?: (error: Error) => void;
|
|
17
|
-
} &
|
|
16
|
+
} & ActionParams;
|
|
18
17
|
export default class FlowModel {
|
|
19
18
|
/**
|
|
20
19
|
* 流程支持的节点类型
|
|
@@ -27,7 +26,7 @@ export default class FlowModel {
|
|
|
27
26
|
/**
|
|
28
27
|
* 待执行的队列,当流程正在执行时,如果再次触发执行。那么会将执行参数放入到队列中,等待上一次执行完成后再执行。
|
|
29
28
|
*/
|
|
30
|
-
|
|
29
|
+
executeList: ExecParams[];
|
|
31
30
|
/**
|
|
32
31
|
* 当前正在执行。当监听到调度器执行完成时,出触发执行参数中的回调,告知外部执行完成。
|
|
33
32
|
*/
|
|
@@ -114,16 +113,17 @@ export default class FlowModel {
|
|
|
114
113
|
* 一个流程存在着两个开始节点,A和B,A和B的下一个节点都是C,C的下两个节点是D和E。
|
|
115
114
|
* 外部分别触发了A和B的执行,那么A和B的执行是串行的(也就是需要A执行完成后再执行B),但是D和E的执行是并行的。
|
|
116
115
|
* 如果希望A和B的执行是并行的,就不能使用同一个流程模型执行,应该初始化两个。
|
|
116
|
+
* TODO: 去掉此处的对列,直接使用调度器的队列。
|
|
117
117
|
*/
|
|
118
118
|
execute(params: ExecParams): Promise<void>;
|
|
119
119
|
resume(params: ExecParams): Promise<void>;
|
|
120
120
|
/**
|
|
121
|
-
* 创建节点实例, 每个节点实例都会有一个唯一的
|
|
122
|
-
* 通过executionId、nodeId、
|
|
121
|
+
* 创建节点实例, 每个节点实例都会有一个唯一的actionId。
|
|
122
|
+
* 通过executionId、nodeId、actionId可以唯一确定一个节点的某一次执行。
|
|
123
123
|
* @param nodeId 节点Id
|
|
124
124
|
* @returns 节点示例
|
|
125
125
|
*/
|
|
126
|
-
|
|
126
|
+
createAction(nodeId: string): import("./nodes/BaseNode").default;
|
|
127
127
|
/**
|
|
128
128
|
* 更新流程全局数据
|
|
129
129
|
*/
|
|
@@ -132,7 +132,7 @@ export default class FlowModel {
|
|
|
132
132
|
* 在执行完成后,通知外部此次执行完成。
|
|
133
133
|
* 如果还存在待执行的任务,那么继续执行。
|
|
134
134
|
*/
|
|
135
|
-
private
|
|
135
|
+
private onExecuteFinished;
|
|
136
136
|
/**
|
|
137
137
|
* 从待执行队列中取出需要执行的内容。
|
|
138
138
|
* 会依次判断是否有taskId、nodeId、executionId。
|
package/es/FlowModel.js
CHANGED
|
@@ -68,7 +68,7 @@ var FlowModel = /** @class */ (function () {
|
|
|
68
68
|
// 流程包含的节点类型
|
|
69
69
|
this.nodeModelMap = nodeModelMap;
|
|
70
70
|
// 需要执行的队列
|
|
71
|
-
this.
|
|
71
|
+
this.executeList = [];
|
|
72
72
|
// 执行中的任务
|
|
73
73
|
this.executingInstance = null;
|
|
74
74
|
// 外部传入的上下文,最终会传递给每个节点
|
|
@@ -83,10 +83,10 @@ var FlowModel = /** @class */ (function () {
|
|
|
83
83
|
recorder: recorder,
|
|
84
84
|
});
|
|
85
85
|
this.scheduler.on(EVENT_INSTANCE_COMPLETE, function (result) {
|
|
86
|
-
_this.
|
|
86
|
+
_this.onExecuteFinished(result);
|
|
87
87
|
});
|
|
88
88
|
this.scheduler.on(EVENT_INSTANCE_INTERRUPTED, function (result) {
|
|
89
|
-
_this.
|
|
89
|
+
_this.onExecuteFinished(result);
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
FlowModel.prototype.setStartNodeType = function (startNodeType) {
|
|
@@ -175,16 +175,12 @@ var FlowModel = /** @class */ (function () {
|
|
|
175
175
|
* 一个流程存在着两个开始节点,A和B,A和B的下一个节点都是C,C的下两个节点是D和E。
|
|
176
176
|
* 外部分别触发了A和B的执行,那么A和B的执行是串行的(也就是需要A执行完成后再执行B),但是D和E的执行是并行的。
|
|
177
177
|
* 如果希望A和B的执行是并行的,就不能使用同一个流程模型执行,应该初始化两个。
|
|
178
|
+
* TODO: 去掉此处的对列,直接使用调度器的队列。
|
|
178
179
|
*/
|
|
179
180
|
FlowModel.prototype.execute = function (params) {
|
|
180
181
|
return __awaiter(this, void 0, void 0, function () {
|
|
181
182
|
return __generator(this, function (_a) {
|
|
182
|
-
this.
|
|
183
|
-
if (this.isRunning) {
|
|
184
|
-
return [2 /*return*/];
|
|
185
|
-
}
|
|
186
|
-
this.isRunning = true;
|
|
187
|
-
this.createExecution();
|
|
183
|
+
this.createExecution(params);
|
|
188
184
|
return [2 /*return*/];
|
|
189
185
|
});
|
|
190
186
|
});
|
|
@@ -192,31 +188,26 @@ var FlowModel = /** @class */ (function () {
|
|
|
192
188
|
FlowModel.prototype.resume = function (params) {
|
|
193
189
|
return __awaiter(this, void 0, void 0, function () {
|
|
194
190
|
return __generator(this, function (_a) {
|
|
195
|
-
this.
|
|
196
|
-
if (this.isRunning) {
|
|
197
|
-
return [2 /*return*/];
|
|
198
|
-
}
|
|
199
|
-
this.isRunning = true;
|
|
200
|
-
this.createExecution();
|
|
191
|
+
this.createExecution(params);
|
|
201
192
|
return [2 /*return*/];
|
|
202
193
|
});
|
|
203
194
|
});
|
|
204
195
|
};
|
|
205
196
|
/**
|
|
206
|
-
* 创建节点实例, 每个节点实例都会有一个唯一的
|
|
207
|
-
* 通过executionId、nodeId、
|
|
197
|
+
* 创建节点实例, 每个节点实例都会有一个唯一的actionId。
|
|
198
|
+
* 通过executionId、nodeId、actionId可以唯一确定一个节点的某一次执行。
|
|
208
199
|
* @param nodeId 节点Id
|
|
209
200
|
* @returns 节点示例
|
|
210
201
|
*/
|
|
211
|
-
FlowModel.prototype.
|
|
202
|
+
FlowModel.prototype.createAction = function (nodeId) {
|
|
212
203
|
var nodeConfig = this.nodeConfigMap.get(nodeId);
|
|
213
204
|
var NodeModel = this.nodeModelMap.get(nodeConfig.type);
|
|
214
|
-
var
|
|
205
|
+
var action = new NodeModel({
|
|
215
206
|
nodeConfig: nodeConfig,
|
|
216
207
|
globalData: this.globalData,
|
|
217
208
|
context: this.context,
|
|
218
209
|
});
|
|
219
|
-
return
|
|
210
|
+
return action;
|
|
220
211
|
};
|
|
221
212
|
/**
|
|
222
213
|
* 更新流程全局数据
|
|
@@ -228,17 +219,12 @@ var FlowModel = /** @class */ (function () {
|
|
|
228
219
|
* 在执行完成后,通知外部此次执行完成。
|
|
229
220
|
* 如果还存在待执行的任务,那么继续执行。
|
|
230
221
|
*/
|
|
231
|
-
FlowModel.prototype.
|
|
232
|
-
var
|
|
233
|
-
if (
|
|
234
|
-
callback
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (this.executeQueue.length > 0) {
|
|
238
|
-
this.createExecution();
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
this.isRunning = false;
|
|
222
|
+
FlowModel.prototype.onExecuteFinished = function (result) {
|
|
223
|
+
var index = this.executeList.findIndex(function (i) { return i.executionId === result.executionId; });
|
|
224
|
+
if (index !== -1) {
|
|
225
|
+
var callback = this.executeList[index].callback;
|
|
226
|
+
this.executeList.splice(index, 1);
|
|
227
|
+
callback && callback(result);
|
|
242
228
|
}
|
|
243
229
|
};
|
|
244
230
|
/**
|
|
@@ -248,21 +234,21 @@ var FlowModel = /** @class */ (function () {
|
|
|
248
234
|
* 若存在nodeId,那么表示从指定节点开始执行。
|
|
249
235
|
* 若都不存在,那么新建一个executionId,从开始节点开始执行。
|
|
250
236
|
*/
|
|
251
|
-
FlowModel.prototype.createExecution = function () {
|
|
237
|
+
FlowModel.prototype.createExecution = function (execParams) {
|
|
252
238
|
var _this = this;
|
|
253
|
-
|
|
254
|
-
this.executingInstance = execParams;
|
|
239
|
+
this.executeList.push(execParams);
|
|
255
240
|
// 如果有taskId,那么表示恢复执行
|
|
256
|
-
if (execParams.
|
|
241
|
+
if (execParams.actionId && execParams.executionId && execParams.nodeId) {
|
|
257
242
|
this.scheduler.resume({
|
|
258
243
|
executionId: execParams.executionId,
|
|
259
|
-
|
|
244
|
+
actionId: execParams.actionId,
|
|
260
245
|
nodeId: execParams.nodeId,
|
|
261
246
|
data: execParams.data,
|
|
262
247
|
});
|
|
263
248
|
return;
|
|
264
249
|
}
|
|
265
|
-
var executionId =
|
|
250
|
+
var executionId = createExecId();
|
|
251
|
+
execParams.executionId = executionId;
|
|
266
252
|
if (execParams.nodeId) {
|
|
267
253
|
var nodeConfig = this.nodeConfigMap.get(execParams.nodeId);
|
|
268
254
|
if (!nodeConfig) {
|
|
@@ -272,7 +258,7 @@ var FlowModel = /** @class */ (function () {
|
|
|
272
258
|
this.startNodes = [nodeConfig];
|
|
273
259
|
}
|
|
274
260
|
this.startNodes.forEach(function (startNode) {
|
|
275
|
-
_this.scheduler.
|
|
261
|
+
_this.scheduler.addAction({
|
|
276
262
|
executionId: executionId,
|
|
277
263
|
nodeId: startNode.id,
|
|
278
264
|
});
|
package/es/Scheduler.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import EventEmitter from './EventEmitter';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ActionParam, NodeParam, ResumeParam } from './types.d';
|
|
3
3
|
import type FlowModel from './FlowModel';
|
|
4
4
|
import type Recorder from './recorder';
|
|
5
|
-
declare type
|
|
5
|
+
declare type ActionParamMap = Map<string, ActionParam>;
|
|
6
6
|
declare type ExecutionId = string;
|
|
7
7
|
/**
|
|
8
8
|
* 调度器
|
|
@@ -18,7 +18,7 @@ export default class Scheduler extends EventEmitter {
|
|
|
18
18
|
* 在每个节点执行完成后,会从集合中删除。
|
|
19
19
|
* 同时会判断此集合中是否还存在和此节点相同的executionId,如果不存在,说明此流程已经执行完成。
|
|
20
20
|
*/
|
|
21
|
-
|
|
21
|
+
actionRunningMap: Map<ExecutionId, ActionParamMap>;
|
|
22
22
|
/**
|
|
23
23
|
* 流程模型,用于创建节点模型。
|
|
24
24
|
*/
|
|
@@ -34,7 +34,7 @@ export default class Scheduler extends EventEmitter {
|
|
|
34
34
|
* 1. 由流程模型将所有的开始节点添加到队列中。
|
|
35
35
|
* 2. 当一个节点执行完成后,将后续的节点添加到队列中。
|
|
36
36
|
*/
|
|
37
|
-
|
|
37
|
+
addAction(nodeParam: NodeParam): void;
|
|
38
38
|
/**
|
|
39
39
|
* 调度器执行下一个任务
|
|
40
40
|
* 1. 提供给流程模型,用户开始执行第一个任务。
|
|
@@ -44,19 +44,19 @@ export default class Scheduler extends EventEmitter {
|
|
|
44
44
|
run(runParams: {
|
|
45
45
|
executionId: string;
|
|
46
46
|
nodeId?: string;
|
|
47
|
-
|
|
47
|
+
actionId?: string;
|
|
48
48
|
}): void;
|
|
49
49
|
/**
|
|
50
50
|
* 恢复某个任务的执行。
|
|
51
51
|
* 可以自定义节点手动实现流程中断,然后通过此方法恢复流程的执行。
|
|
52
52
|
*/
|
|
53
53
|
resume(resumeParam: ResumeParam): Promise<void>;
|
|
54
|
-
private
|
|
55
|
-
private
|
|
56
|
-
private
|
|
54
|
+
private pushActionToRunningMap;
|
|
55
|
+
private removeActionFromRunningMap;
|
|
56
|
+
private hasRunningAction;
|
|
57
57
|
private exec;
|
|
58
58
|
private interrupted;
|
|
59
59
|
private next;
|
|
60
|
-
private
|
|
60
|
+
private saveActionResult;
|
|
61
61
|
}
|
|
62
62
|
export {};
|
package/es/Scheduler.js
CHANGED
|
@@ -60,7 +60,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
60
60
|
};
|
|
61
61
|
import EventEmitter from './EventEmitter';
|
|
62
62
|
import { EVENT_INSTANCE_COMPLETE, EVENT_INSTANCE_INTERRUPTED, FlowStatus, } from './constant/constant';
|
|
63
|
-
import {
|
|
63
|
+
import { createActionId } from './util/ID';
|
|
64
64
|
/**
|
|
65
65
|
* 调度器
|
|
66
66
|
* 通过一个队列维护需要执行的节点,一个集合维护正在执行的节点
|
|
@@ -70,7 +70,7 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
70
70
|
function Scheduler(config) {
|
|
71
71
|
var _this = _super.call(this) || this;
|
|
72
72
|
_this.nodeQueueMap = new Map();
|
|
73
|
-
_this.
|
|
73
|
+
_this.actionRunningMap = new Map();
|
|
74
74
|
_this.flowModel = config.flowModel;
|
|
75
75
|
_this.recorder = config.recorder;
|
|
76
76
|
return _this;
|
|
@@ -80,13 +80,13 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
80
80
|
* 1. 由流程模型将所有的开始节点添加到队列中。
|
|
81
81
|
* 2. 当一个节点执行完成后,将后续的节点添加到队列中。
|
|
82
82
|
*/
|
|
83
|
-
Scheduler.prototype.
|
|
83
|
+
Scheduler.prototype.addAction = function (nodeParam) {
|
|
84
84
|
var executionId = nodeParam.executionId;
|
|
85
85
|
if (!this.nodeQueueMap.has(executionId)) {
|
|
86
86
|
this.nodeQueueMap.set(executionId, []);
|
|
87
87
|
}
|
|
88
|
-
var
|
|
89
|
-
|
|
88
|
+
var currentActionQueue = this.nodeQueueMap.get(executionId);
|
|
89
|
+
currentActionQueue.push(nodeParam);
|
|
90
90
|
};
|
|
91
91
|
/**
|
|
92
92
|
* 调度器执行下一个任务
|
|
@@ -96,22 +96,21 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
96
96
|
*/
|
|
97
97
|
Scheduler.prototype.run = function (runParams) {
|
|
98
98
|
var nodeQueue = this.nodeQueueMap.get(runParams.executionId);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
99
|
+
// 将同一个executionId当前待执行的节点一起执行
|
|
100
|
+
// 避免出现某一个节点执行时间过长,导致其他节点等待时间过长。
|
|
101
|
+
while (nodeQueue.length) {
|
|
102
|
+
var currentNode = nodeQueue.pop();
|
|
103
|
+
var actionId = createActionId();
|
|
104
|
+
var actionParam = __assign(__assign({}, currentNode), { actionId: actionId });
|
|
105
|
+
this.pushActionToRunningMap(actionParam);
|
|
106
|
+
this.exec(actionParam);
|
|
108
107
|
}
|
|
109
|
-
|
|
110
|
-
// 当一个流程在nodeQueueMap和
|
|
108
|
+
if (!this.hasRunningAction(runParams.executionId)) {
|
|
109
|
+
// 当一个流程在nodeQueueMap和actionRunningMap中都不存在执行的节点时,说明这个流程已经执行完成。
|
|
111
110
|
this.emit(EVENT_INSTANCE_COMPLETE, {
|
|
112
111
|
executionId: runParams.executionId,
|
|
113
112
|
nodeId: runParams.nodeId,
|
|
114
|
-
|
|
113
|
+
actionId: runParams.actionId,
|
|
115
114
|
status: FlowStatus.COMPLETED,
|
|
116
115
|
});
|
|
117
116
|
}
|
|
@@ -126,12 +125,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
126
125
|
return __generator(this, function (_a) {
|
|
127
126
|
switch (_a.label) {
|
|
128
127
|
case 0:
|
|
129
|
-
this.
|
|
128
|
+
this.pushActionToRunningMap({
|
|
130
129
|
executionId: resumeParam.executionId,
|
|
131
130
|
nodeId: resumeParam.nodeId,
|
|
132
|
-
|
|
131
|
+
actionId: resumeParam.actionId,
|
|
133
132
|
});
|
|
134
|
-
model = this.flowModel.
|
|
133
|
+
model = this.flowModel.createAction(resumeParam.nodeId);
|
|
135
134
|
return [4 /*yield*/, model.resume(__assign(__assign({}, resumeParam), { next: this.next.bind(this) }))];
|
|
136
135
|
case 1:
|
|
137
136
|
_a.sent();
|
|
@@ -140,44 +139,44 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
140
139
|
});
|
|
141
140
|
});
|
|
142
141
|
};
|
|
143
|
-
Scheduler.prototype.
|
|
144
|
-
var executionId =
|
|
145
|
-
if (!this.
|
|
142
|
+
Scheduler.prototype.pushActionToRunningMap = function (actionParam) {
|
|
143
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
144
|
+
if (!this.actionRunningMap.has(executionId)) {
|
|
146
145
|
var runningMap = new Map();
|
|
147
|
-
this.
|
|
146
|
+
this.actionRunningMap.set(executionId, runningMap);
|
|
148
147
|
}
|
|
149
|
-
this.
|
|
148
|
+
this.actionRunningMap.get(executionId).set(actionId, actionParam);
|
|
150
149
|
};
|
|
151
|
-
Scheduler.prototype.
|
|
152
|
-
var executionId =
|
|
153
|
-
if (!
|
|
150
|
+
Scheduler.prototype.removeActionFromRunningMap = function (actionParam) {
|
|
151
|
+
var executionId = actionParam.executionId, actionId = actionParam.actionId;
|
|
152
|
+
if (!actionId)
|
|
154
153
|
return;
|
|
155
|
-
var runningMap = this.
|
|
154
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
156
155
|
if (!runningMap)
|
|
157
156
|
return;
|
|
158
|
-
runningMap.delete(
|
|
157
|
+
runningMap.delete(actionId);
|
|
159
158
|
};
|
|
160
|
-
Scheduler.prototype.
|
|
161
|
-
var runningMap = this.
|
|
159
|
+
Scheduler.prototype.hasRunningAction = function (executionId) {
|
|
160
|
+
var runningMap = this.actionRunningMap.get(executionId);
|
|
162
161
|
if (!runningMap)
|
|
163
162
|
return false;
|
|
164
163
|
if (runningMap.size === 0) {
|
|
165
|
-
this.
|
|
164
|
+
this.actionRunningMap.delete(executionId);
|
|
166
165
|
return false;
|
|
167
166
|
}
|
|
168
167
|
return true;
|
|
169
168
|
};
|
|
170
|
-
Scheduler.prototype.exec = function (
|
|
169
|
+
Scheduler.prototype.exec = function (actionParam) {
|
|
171
170
|
return __awaiter(this, void 0, void 0, function () {
|
|
172
171
|
var model, execResult;
|
|
173
172
|
return __generator(this, function (_a) {
|
|
174
173
|
switch (_a.label) {
|
|
175
174
|
case 0:
|
|
176
|
-
model = this.flowModel.
|
|
175
|
+
model = this.flowModel.createAction(actionParam.nodeId);
|
|
177
176
|
return [4 /*yield*/, model.execute({
|
|
178
|
-
executionId:
|
|
179
|
-
|
|
180
|
-
nodeId:
|
|
177
|
+
executionId: actionParam.executionId,
|
|
178
|
+
actionId: actionParam.actionId,
|
|
179
|
+
nodeId: actionParam.nodeId,
|
|
181
180
|
next: this.next.bind(this),
|
|
182
181
|
})];
|
|
183
182
|
case 1:
|
|
@@ -185,12 +184,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
185
184
|
if (execResult && execResult.status === FlowStatus.INTERRUPTED) {
|
|
186
185
|
this.interrupted({
|
|
187
186
|
execResult: execResult,
|
|
188
|
-
|
|
187
|
+
actionParam: actionParam,
|
|
189
188
|
});
|
|
190
|
-
this.
|
|
191
|
-
executionId:
|
|
192
|
-
nodeId:
|
|
193
|
-
|
|
189
|
+
this.saveActionResult({
|
|
190
|
+
executionId: actionParam.executionId,
|
|
191
|
+
nodeId: actionParam.nodeId,
|
|
192
|
+
actionId: actionParam.actionId,
|
|
194
193
|
nodeType: execResult.nodeType,
|
|
195
194
|
properties: execResult.properties,
|
|
196
195
|
outgoing: [],
|
|
@@ -199,7 +198,7 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
199
198
|
detail: execResult.detail,
|
|
200
199
|
},
|
|
201
200
|
});
|
|
202
|
-
this.
|
|
201
|
+
this.removeActionFromRunningMap(actionParam);
|
|
203
202
|
}
|
|
204
203
|
return [2 /*return*/];
|
|
205
204
|
}
|
|
@@ -207,12 +206,12 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
207
206
|
});
|
|
208
207
|
};
|
|
209
208
|
Scheduler.prototype.interrupted = function (_a) {
|
|
210
|
-
var execResult = _a.execResult,
|
|
209
|
+
var execResult = _a.execResult, actionParam = _a.actionParam;
|
|
211
210
|
this.emit(EVENT_INSTANCE_INTERRUPTED, {
|
|
212
|
-
executionId:
|
|
211
|
+
executionId: actionParam.executionId,
|
|
213
212
|
status: FlowStatus.INTERRUPTED,
|
|
214
|
-
nodeId:
|
|
215
|
-
|
|
213
|
+
nodeId: actionParam.nodeId,
|
|
214
|
+
actionId: actionParam.actionId,
|
|
216
215
|
detail: execResult.detail,
|
|
217
216
|
});
|
|
218
217
|
};
|
|
@@ -220,24 +219,24 @@ var Scheduler = /** @class */ (function (_super) {
|
|
|
220
219
|
var _this = this;
|
|
221
220
|
if (data.outgoing && data.outgoing.length > 0) {
|
|
222
221
|
data.outgoing.forEach(function (item) {
|
|
223
|
-
_this.
|
|
222
|
+
_this.addAction({
|
|
224
223
|
executionId: data.executionId,
|
|
225
224
|
nodeId: item.target,
|
|
226
225
|
});
|
|
227
226
|
});
|
|
228
227
|
}
|
|
229
|
-
this.
|
|
230
|
-
this.
|
|
228
|
+
this.saveActionResult(data);
|
|
229
|
+
this.removeActionFromRunningMap(data);
|
|
231
230
|
this.run({
|
|
232
231
|
executionId: data.executionId,
|
|
233
232
|
nodeId: data.nodeId,
|
|
234
|
-
|
|
233
|
+
actionId: data.actionId,
|
|
235
234
|
});
|
|
236
235
|
};
|
|
237
|
-
Scheduler.prototype.
|
|
238
|
-
this.recorder.
|
|
236
|
+
Scheduler.prototype.saveActionResult = function (data) {
|
|
237
|
+
this.recorder.addActionRecord({
|
|
239
238
|
executionId: data.executionId,
|
|
240
|
-
|
|
239
|
+
actionId: data.actionId,
|
|
241
240
|
nodeId: data.nodeId,
|
|
242
241
|
nodeType: data.nodeType,
|
|
243
242
|
timestamp: Date.now(),
|
package/es/constant/constant.js
CHANGED
|
@@ -11,10 +11,10 @@ export var FlowStatus;
|
|
|
11
11
|
FlowStatus["RUNNING"] = "running";
|
|
12
12
|
FlowStatus["ERROR"] = "error";
|
|
13
13
|
})(FlowStatus || (FlowStatus = {}));
|
|
14
|
-
//
|
|
15
|
-
export var
|
|
16
|
-
(function (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})(
|
|
14
|
+
// action status
|
|
15
|
+
export var ActionStatus;
|
|
16
|
+
(function (ActionStatus) {
|
|
17
|
+
ActionStatus["SUCCESS"] = "success";
|
|
18
|
+
ActionStatus["ERROR"] = "error";
|
|
19
|
+
ActionStatus["INTERRUPTED"] = "interrupted";
|
|
20
|
+
})(ActionStatus || (ActionStatus = {}));
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
+
declare const createContext: (globalData: any) => any;
|
|
2
|
+
declare const runInContext: (code: any, context: any) => any;
|
|
1
3
|
declare const runInBrowserContext: (code: string, globalData?: any) => Promise<any>;
|
|
2
|
-
export { runInBrowserContext, };
|
|
4
|
+
export { runInBrowserContext, createContext, runInContext, };
|