bpmn-elements 6.0.1 → 8.0.1
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 +341 -0
- package/README.md +3 -0
- package/dist/index.js +52 -44
- package/dist/src/Api.js +77 -76
- package/dist/src/Context.js +176 -172
- package/dist/src/Environment.js +110 -102
- package/dist/src/EventBroker.js +89 -88
- package/dist/src/ExtensionsMapper.js +2 -2
- package/dist/src/MessageFormatter.js +164 -95
- package/dist/src/Scripts.js +6 -2
- package/dist/src/activity/Activity.js +1105 -916
- package/dist/src/activity/ActivityExecution.js +342 -297
- package/dist/src/activity/Dummy.js +3 -3
- package/dist/src/definition/Definition.js +498 -444
- package/dist/src/definition/DefinitionExecution.js +710 -408
- package/dist/src/error/Errors.js +17 -7
- package/dist/src/eventDefinitions/CancelEventDefinition.js +190 -150
- package/dist/src/eventDefinitions/CompensateEventDefinition.js +194 -161
- package/dist/src/eventDefinitions/ConditionalEventDefinition.js +197 -135
- package/dist/src/eventDefinitions/ErrorEventDefinition.js +207 -165
- package/dist/src/eventDefinitions/EscalationEventDefinition.js +175 -141
- package/dist/src/eventDefinitions/EventDefinitionExecution.js +157 -129
- package/dist/src/eventDefinitions/LinkEventDefinition.js +174 -149
- package/dist/src/eventDefinitions/MessageEventDefinition.js +213 -176
- package/dist/src/eventDefinitions/SignalEventDefinition.js +203 -161
- package/dist/src/eventDefinitions/TerminateEventDefinition.js +21 -23
- package/dist/src/eventDefinitions/TimerEventDefinition.js +243 -228
- package/dist/src/events/BoundaryEvent.js +180 -144
- package/dist/src/events/EndEvent.js +18 -23
- package/dist/src/events/IntermediateCatchEvent.js +44 -58
- package/dist/src/events/IntermediateThrowEvent.js +18 -23
- package/dist/src/events/StartEvent.js +109 -94
- package/dist/src/flows/Association.js +94 -100
- package/dist/src/flows/MessageFlow.js +86 -103
- package/dist/src/flows/SequenceFlow.js +173 -182
- package/dist/src/gateways/EventBasedGateway.js +88 -84
- package/dist/src/gateways/ExclusiveGateway.js +13 -16
- package/dist/src/gateways/InclusiveGateway.js +11 -14
- package/dist/src/gateways/ParallelGateway.js +11 -14
- package/dist/src/getPropertyValue.js +34 -34
- package/dist/src/io/BpmnIO.js +17 -14
- package/dist/src/io/EnvironmentDataObject.js +33 -29
- package/dist/src/io/EnvironmentDataStore.js +33 -29
- package/dist/src/io/EnvironmentDataStoreReference.js +35 -31
- package/dist/src/io/InputOutputSpecification.js +177 -168
- package/dist/src/io/Properties.js +117 -124
- package/dist/src/messageHelper.js +1 -1
- package/dist/src/process/Process.js +439 -362
- package/dist/src/process/ProcessExecution.js +748 -646
- package/dist/src/shared.js +2 -2
- package/dist/src/tasks/CallActivity.js +160 -0
- package/dist/src/tasks/LoopCharacteristics.js +309 -330
- package/dist/src/tasks/ReceiveTask.js +233 -182
- package/dist/src/tasks/ScriptTask.js +35 -41
- package/dist/src/tasks/ServiceImplementation.js +13 -20
- package/dist/src/tasks/ServiceTask.js +82 -75
- package/dist/src/tasks/SignalTask.js +97 -93
- package/dist/src/tasks/StandardLoopCharacteristics.js +1 -1
- package/dist/src/tasks/SubProcess.js +193 -175
- package/dist/src/tasks/Task.js +17 -19
- package/index.js +2 -0
- package/package.json +16 -16
- package/src/Api.js +65 -59
- package/src/Context.js +145 -140
- package/src/Environment.js +116 -100
- package/src/EventBroker.js +67 -68
- package/src/ExtensionsMapper.js +2 -2
- package/src/MessageFormatter.js +132 -74
- package/src/activity/Activity.js +914 -776
- package/src/activity/ActivityExecution.js +293 -247
- package/src/activity/Dummy.js +2 -2
- package/src/definition/Definition.js +437 -401
- package/src/definition/DefinitionExecution.js +598 -340
- package/src/error/Errors.js +11 -6
- package/src/eventDefinitions/CancelEventDefinition.js +164 -121
- package/src/eventDefinitions/CompensateEventDefinition.js +159 -124
- package/src/eventDefinitions/ConditionalEventDefinition.js +147 -104
- package/src/eventDefinitions/ErrorEventDefinition.js +190 -131
- package/src/eventDefinitions/EscalationEventDefinition.js +139 -101
- package/src/eventDefinitions/EventDefinitionExecution.js +127 -95
- package/src/eventDefinitions/LinkEventDefinition.js +160 -129
- package/src/eventDefinitions/MessageEventDefinition.js +178 -121
- package/src/eventDefinitions/SignalEventDefinition.js +162 -106
- package/src/eventDefinitions/TerminateEventDefinition.js +19 -19
- package/src/eventDefinitions/TimerEventDefinition.js +202 -167
- package/src/events/BoundaryEvent.js +156 -115
- package/src/events/EndEvent.js +15 -18
- package/src/events/IntermediateCatchEvent.js +40 -44
- package/src/events/IntermediateThrowEvent.js +15 -18
- package/src/events/StartEvent.js +84 -50
- package/src/flows/Association.js +98 -112
- package/src/flows/MessageFlow.js +81 -97
- package/src/flows/SequenceFlow.js +146 -160
- package/src/gateways/EventBasedGateway.js +75 -68
- package/src/gateways/ExclusiveGateway.js +8 -13
- package/src/gateways/InclusiveGateway.js +8 -13
- package/src/gateways/ParallelGateway.js +8 -13
- package/src/getPropertyValue.js +34 -33
- package/src/io/BpmnIO.js +20 -15
- package/src/io/EnvironmentDataObject.js +29 -18
- package/src/io/EnvironmentDataStore.js +29 -18
- package/src/io/EnvironmentDataStoreReference.js +31 -20
- package/src/io/InputOutputSpecification.js +154 -157
- package/src/io/Properties.js +95 -97
- package/src/process/Process.js +378 -333
- package/src/process/ProcessExecution.js +603 -553
- package/src/tasks/CallActivity.js +130 -0
- package/src/tasks/LoopCharacteristics.js +290 -289
- package/src/tasks/ReceiveTask.js +174 -107
- package/src/tasks/ScriptTask.js +27 -30
- package/src/tasks/ServiceImplementation.js +13 -18
- package/src/tasks/ServiceTask.js +67 -60
- package/src/tasks/SignalTask.js +77 -52
- package/src/tasks/StandardLoopCharacteristics.js +1 -1
- package/src/tasks/SubProcess.js +184 -157
- package/src/tasks/Task.js +15 -19
|
@@ -10,25 +10,22 @@ var _Errors = require("../error/Errors");
|
|
|
10
10
|
var _messageHelper = require("../messageHelper");
|
|
11
11
|
|
|
12
12
|
function LoopCharacteristics(activity, loopCharacteristics) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
broker,
|
|
16
|
-
environment
|
|
17
|
-
} = activity;
|
|
18
|
-
const {
|
|
19
|
-
batchSize = 50
|
|
20
|
-
} = environment.settings;
|
|
13
|
+
this.activity = activity;
|
|
14
|
+
this.loopCharacteristics = loopCharacteristics;
|
|
21
15
|
const {
|
|
22
16
|
type = 'LoopCharacteristics',
|
|
23
17
|
behaviour = {}
|
|
24
18
|
} = loopCharacteristics;
|
|
19
|
+
this.type = type;
|
|
25
20
|
const {
|
|
26
21
|
isSequential = false,
|
|
27
|
-
collection
|
|
28
|
-
elementVariable = 'item'
|
|
22
|
+
collection
|
|
29
23
|
} = behaviour;
|
|
24
|
+
this.isSequential = isSequential;
|
|
25
|
+
this.collection = collection;
|
|
30
26
|
let completionCondition, startCondition, loopCardinality;
|
|
31
27
|
if ('loopCardinality' in behaviour) loopCardinality = behaviour.loopCardinality;else if ('loopMaximum' in behaviour) loopCardinality = behaviour.loopMaximum;
|
|
28
|
+
this.loopCardinality = loopCardinality;
|
|
32
29
|
|
|
33
30
|
if (behaviour.loopCondition) {
|
|
34
31
|
if (behaviour.testBefore) startCondition = behaviour.loopCondition;else completionCondition = behaviour.loopCondition;
|
|
@@ -38,344 +35,326 @@ function LoopCharacteristics(activity, loopCharacteristics) {
|
|
|
38
35
|
completionCondition = behaviour.completionCondition;
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
if (collection) {
|
|
39
|
+
this.loopType = 'collection';
|
|
40
|
+
this.elementVariable = behaviour.elementVariable || 'item';
|
|
41
|
+
} else if (completionCondition) this.loopType = 'complete condition';else if (startCondition) this.loopType = 'start condition';else if (loopCardinality) this.loopType = 'cardinality';
|
|
42
|
+
|
|
43
|
+
this.characteristics = null;
|
|
44
|
+
this.execution = null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
LoopCharacteristics.prototype.execute = function execute(executeMessage) {
|
|
48
|
+
if (!executeMessage) throw new TypeError('LoopCharacteristics execution requires message');
|
|
49
|
+
const chr = this.characteristics = this.characteristics || new Characteristics(this.activity, this.loopCharacteristics, executeMessage);
|
|
50
|
+
if (chr.cardinality === 0) return chr.complete();
|
|
51
|
+
const execution = this.isSequential ? new SequentialLoopCharacteristics(this.activity, chr) : new ParallelLoopCharacteristics(this.activity, chr);
|
|
52
|
+
return execution.execute(executeMessage);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
function SequentialLoopCharacteristics(activity, characteristics) {
|
|
56
|
+
this.activity = activity;
|
|
57
|
+
this.id = activity.id;
|
|
58
|
+
this.characteristics = characteristics;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
SequentialLoopCharacteristics.prototype.execute = function execute(executeMessage) {
|
|
43
62
|
const {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const apiConsumerTag = '_api-multi-instance-tag';
|
|
49
|
-
broker.cancel(apiConsumerTag);
|
|
50
|
-
let loopSettings;
|
|
51
|
-
const characteristicsApi = {
|
|
52
|
-
type,
|
|
53
|
-
loopType,
|
|
54
|
-
collection: collectionExpression,
|
|
55
|
-
elementVariable,
|
|
56
|
-
isSequential,
|
|
57
|
-
loopCardinality,
|
|
58
|
-
execute
|
|
59
|
-
};
|
|
60
|
-
return characteristicsApi;
|
|
63
|
+
routingKey: executeRoutingKey,
|
|
64
|
+
redelivered: isRedelivered
|
|
65
|
+
} = executeMessage.fields || {};
|
|
66
|
+
const chr = this.characteristics;
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (completionCondition) return 'complete condition';
|
|
65
|
-
if (startCondition) return 'start condition';
|
|
66
|
-
if (loopCardinality) return 'cardinality';
|
|
68
|
+
if (!chr.cardinality && !chr.startCondition && !chr.completionCondition) {
|
|
69
|
+
throw new _Errors.RunError(`<${this.id}> cardinality, collection, or condition is required in sequential loops`, executeMessage);
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
if (!executeMessage) throw new Error('LoopCharacteristics execution requires message');
|
|
71
|
-
const {
|
|
72
|
-
routingKey: executeRoutingKey,
|
|
73
|
-
redelivered: isRedelivered
|
|
74
|
-
} = executeMessage.fields || {};
|
|
75
|
-
const {
|
|
76
|
-
executionId: parentExecutionId
|
|
77
|
-
} = executeMessage.content;
|
|
78
|
-
if (!getCharacteristics()) return;
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
return isSequential ? executeSequential() : executeParallel();
|
|
82
|
-
} catch (err) {
|
|
83
|
-
return activity.emitFatal(new _Errors.ActivityError(err.message, executeMessage, err), executeMessage.content);
|
|
84
|
-
}
|
|
72
|
+
let startIndex = 0;
|
|
85
73
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
getContent: getStartContent
|
|
90
|
-
} = getCharacteristics();
|
|
91
|
-
if (cardinality === 0) return complete();
|
|
92
|
-
if (!cardinality && !startCondition && !completionCondition) return activity.emitFatal(new _Errors.ActivityError(`<${id}> cardinality, collection, or condition is required in sequential loops`, executeMessage), getStartContent());
|
|
93
|
-
let startIndex = 0;
|
|
94
|
-
|
|
95
|
-
if (isRedelivered && executeRoutingKey === 'execute.iteration.next') {
|
|
96
|
-
startIndex = executeMessage.content.index;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
subscribe(onCompleteMessage);
|
|
100
|
-
return startNext(startIndex, isRedelivered);
|
|
101
|
-
|
|
102
|
-
function startNext(index, ignoreIfExecuting) {
|
|
103
|
-
const content = next(index);
|
|
104
|
-
if (!content) return;
|
|
105
|
-
const characteristics = getCharacteristics();
|
|
106
|
-
|
|
107
|
-
if (startCondition && isConditionMet(startCondition, {
|
|
108
|
-
content
|
|
109
|
-
})) {
|
|
110
|
-
debug(`<${parentExecutionId} (${id})> start condition met`);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
debug(`<${content.executionId} (${id})>`, ignoreIfExecuting ? 'resume' : 'start', `sequential iteration index ${content.index}`);
|
|
115
|
-
broker.publish('execution', 'execute.iteration.next', { ...content,
|
|
116
|
-
...characteristics.getContent(),
|
|
117
|
-
index,
|
|
118
|
-
preventComplete: true,
|
|
119
|
-
output: characteristics.output.slice(),
|
|
120
|
-
state: 'iteration.next'
|
|
121
|
-
});
|
|
122
|
-
broker.publish('execution', 'execute.start', { ...content,
|
|
123
|
-
ignoreIfExecuting
|
|
124
|
-
});
|
|
125
|
-
return content;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function onCompleteMessage(_, message) {
|
|
129
|
-
const {
|
|
130
|
-
content
|
|
131
|
-
} = message;
|
|
132
|
-
const loopOutput = getCharacteristics().output;
|
|
133
|
-
if (content.output !== undefined) loopOutput[content.index] = content.output;
|
|
134
|
-
broker.publish('execution', 'execute.iteration.completed', { ...message.content,
|
|
135
|
-
...getCharacteristics().getContent(),
|
|
136
|
-
preventComplete: true,
|
|
137
|
-
output: loopOutput.slice(),
|
|
138
|
-
state: 'iteration.completed'
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
if (isConditionMet(completionCondition, message, loopOutput)) {
|
|
142
|
-
debug(`<${parentExecutionId} (${id})> complete condition met`);
|
|
143
|
-
} else if (startNext(content.index + 1)) return;
|
|
144
|
-
|
|
145
|
-
debug(`<${parentExecutionId} (${id})> sequential loop completed`);
|
|
146
|
-
return complete(content);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function complete(content) {
|
|
150
|
-
stop();
|
|
151
|
-
const {
|
|
152
|
-
getContent,
|
|
153
|
-
output
|
|
154
|
-
} = getCharacteristics();
|
|
155
|
-
return broker.publish('execution', 'execute.completed', { ...content,
|
|
156
|
-
...getContent(),
|
|
157
|
-
output
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
74
|
+
if (isRedelivered && executeRoutingKey === 'execute.iteration.next') {
|
|
75
|
+
startIndex = executeMessage.content.index;
|
|
76
|
+
}
|
|
161
77
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
getContent: getStartContent
|
|
166
|
-
} = getCharacteristics();
|
|
167
|
-
if (cardinality === 0) return complete();
|
|
168
|
-
if (!cardinality) return activity.emitFatal(new _Errors.ActivityError(`<${id}> cardinality or collection is required in parallel loops`, executeMessage), getStartContent());
|
|
169
|
-
let index = 0,
|
|
170
|
-
running = 0;
|
|
171
|
-
|
|
172
|
-
if (isRedelivered) {
|
|
173
|
-
if (!isNaN(executeMessage.content.index)) index = executeMessage.content.index;
|
|
174
|
-
if (!isNaN(executeMessage.content.running)) running = executeMessage.content.running;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
subscribe(onCompleteMessage);
|
|
178
|
-
if (isRedelivered) return;
|
|
179
|
-
return startBatch();
|
|
180
|
-
|
|
181
|
-
function startBatch() {
|
|
182
|
-
const {
|
|
183
|
-
output: loopOutput,
|
|
184
|
-
getContent
|
|
185
|
-
} = getCharacteristics();
|
|
186
|
-
const batch = [];
|
|
187
|
-
let startContent = next(index);
|
|
188
|
-
|
|
189
|
-
do {
|
|
190
|
-
debug(`<${parentExecutionId} (${id})> start parallel iteration index ${index}`);
|
|
191
|
-
batch.push(startContent);
|
|
192
|
-
running++;
|
|
193
|
-
index++;
|
|
194
|
-
|
|
195
|
-
if (index >= cardinality || running >= batchSize) {
|
|
196
|
-
break;
|
|
197
|
-
}
|
|
198
|
-
} while (startContent = next(index));
|
|
199
|
-
|
|
200
|
-
broker.publish('execution', 'execute.iteration.batch', { ...getContent(),
|
|
201
|
-
index,
|
|
202
|
-
running,
|
|
203
|
-
output: loopOutput,
|
|
204
|
-
preventComplete: true
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
for (const content of batch) {
|
|
208
|
-
broker.publish('execution', 'execute.start', content);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function onCompleteMessage(_, message) {
|
|
213
|
-
const {
|
|
214
|
-
content
|
|
215
|
-
} = message;
|
|
216
|
-
const {
|
|
217
|
-
output: loopOutput
|
|
218
|
-
} = getCharacteristics();
|
|
219
|
-
if (content.output !== undefined) loopOutput[content.index] = content.output;
|
|
220
|
-
running--;
|
|
221
|
-
broker.publish('execution', 'execute.iteration.completed', { ...content,
|
|
222
|
-
...getCharacteristics().getContent(),
|
|
223
|
-
index,
|
|
224
|
-
running,
|
|
225
|
-
output: loopOutput,
|
|
226
|
-
state: 'iteration.completed',
|
|
227
|
-
preventComplete: true
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
if (running <= 0 && !next(index)) {
|
|
231
|
-
return complete(content);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (isConditionMet(completionCondition, message)) {
|
|
235
|
-
return complete(content);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
if (running <= 0) {
|
|
239
|
-
running = 0;
|
|
240
|
-
startBatch();
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function complete(content) {
|
|
245
|
-
stop();
|
|
246
|
-
const {
|
|
247
|
-
getContent,
|
|
248
|
-
output
|
|
249
|
-
} = getCharacteristics();
|
|
250
|
-
return broker.publish('execution', 'execute.completed', { ...content,
|
|
251
|
-
...getContent(),
|
|
252
|
-
output
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
}
|
|
78
|
+
chr.subscribe(this._onCompleteMessage.bind(this));
|
|
79
|
+
return this._startNext(startIndex, isRedelivered);
|
|
80
|
+
};
|
|
256
81
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
collection,
|
|
262
|
-
parent,
|
|
263
|
-
getContent
|
|
264
|
-
} = getCharacteristics();
|
|
265
|
-
const content = { ...getContent(),
|
|
266
|
-
isRootScope: undefined,
|
|
267
|
-
executionId,
|
|
268
|
-
isMultiInstance: true,
|
|
269
|
-
index,
|
|
270
|
-
parent
|
|
271
|
-
};
|
|
272
|
-
if (isComplete(content)) return;
|
|
273
|
-
|
|
274
|
-
if (collection) {
|
|
275
|
-
content[elementVariable] = collection[index];
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return content;
|
|
279
|
-
|
|
280
|
-
function isComplete() {
|
|
281
|
-
if (cardinality > 0 && index >= cardinality) return true;
|
|
282
|
-
if (collection && index >= collection.length) return true;
|
|
283
|
-
}
|
|
284
|
-
}
|
|
82
|
+
SequentialLoopCharacteristics.prototype._startNext = function startNext(index, ignoreIfExecuting) {
|
|
83
|
+
const chr = this.characteristics;
|
|
84
|
+
const content = chr.next(index);
|
|
85
|
+
if (!content) return;
|
|
285
86
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
87
|
+
if (chr.isStartConditionMet({
|
|
88
|
+
content
|
|
89
|
+
})) {
|
|
90
|
+
chr.debug('start condition met');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
chr.debug(`${ignoreIfExecuting ? 'resume' : 'start'} sequential iteration index ${content.index}`);
|
|
95
|
+
const broker = this.activity.broker;
|
|
96
|
+
broker.publish('execution', 'execute.iteration.next', { ...content,
|
|
97
|
+
...chr.getContent(),
|
|
98
|
+
index,
|
|
99
|
+
preventComplete: true,
|
|
100
|
+
output: chr.output.slice(),
|
|
101
|
+
state: 'iteration.next'
|
|
102
|
+
});
|
|
103
|
+
broker.publish('execution', 'execute.start', { ...content,
|
|
104
|
+
ignoreIfExecuting
|
|
105
|
+
});
|
|
106
|
+
return content;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
SequentialLoopCharacteristics.prototype._onCompleteMessage = function onCompleteMessage(_, message) {
|
|
110
|
+
const {
|
|
111
|
+
content
|
|
112
|
+
} = message;
|
|
113
|
+
const chr = this.characteristics;
|
|
114
|
+
const loopOutput = chr.output;
|
|
115
|
+
if (content.output !== undefined) loopOutput[content.index] = content.output;
|
|
116
|
+
this.activity.broker.publish('execution', 'execute.iteration.completed', { ...message.content,
|
|
117
|
+
...chr.getContent(),
|
|
118
|
+
preventComplete: true,
|
|
119
|
+
output: loopOutput.slice(),
|
|
120
|
+
state: 'iteration.completed'
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (chr.isCompletionConditionMet(message, loopOutput)) {
|
|
124
|
+
chr.debug('complete condition met');
|
|
125
|
+
} else if (this._startNext(content.index + 1)) return;
|
|
126
|
+
|
|
127
|
+
chr.debug('sequential loop completed');
|
|
128
|
+
return chr.complete(content);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
function ParallelLoopCharacteristics(activity, characteristics) {
|
|
132
|
+
this.activity = activity;
|
|
133
|
+
this.id = activity.id;
|
|
134
|
+
this.characteristics = characteristics;
|
|
135
|
+
this.running = 0;
|
|
136
|
+
this.index = 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
ParallelLoopCharacteristics.prototype.execute = function execute(executeMessage) {
|
|
140
|
+
const chr = this.characteristics;
|
|
141
|
+
if (!chr.cardinality) throw new _Errors.RunError(`<${this.id}> cardinality or collection is required in parallel loops`, executeMessage);
|
|
142
|
+
const isRedelivered = executeMessage.fields.redelivered;
|
|
143
|
+
|
|
144
|
+
if (isRedelivered) {
|
|
145
|
+
if (!isNaN(executeMessage.content.index)) this.index = executeMessage.content.index;
|
|
146
|
+
if (!isNaN(executeMessage.content.running)) this.running = executeMessage.content.running;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
chr.subscribe(this._onCompleteMessage.bind(this));
|
|
150
|
+
if (isRedelivered) return;
|
|
151
|
+
return this._startBatch();
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
ParallelLoopCharacteristics.prototype._startBatch = function startBatch() {
|
|
155
|
+
const chr = this.characteristics;
|
|
156
|
+
const cardinality = chr.cardinality;
|
|
157
|
+
const batch = [];
|
|
158
|
+
let startContent = chr.next(this.index);
|
|
159
|
+
|
|
160
|
+
do {
|
|
161
|
+
chr.debug(`start parallel iteration index ${this.index}`);
|
|
162
|
+
batch.push(startContent);
|
|
163
|
+
this.running++;
|
|
164
|
+
this.index++;
|
|
165
|
+
|
|
166
|
+
if (this.index >= cardinality || this.running >= chr.batchSize) {
|
|
167
|
+
break;
|
|
315
168
|
}
|
|
169
|
+
} while (startContent = chr.next(this.index));
|
|
170
|
+
|
|
171
|
+
const broker = this.activity.broker;
|
|
172
|
+
broker.publish('execution', 'execute.iteration.batch', { ...chr.getContent(),
|
|
173
|
+
index: this.index,
|
|
174
|
+
running: this.running,
|
|
175
|
+
output: chr.output,
|
|
176
|
+
preventComplete: true
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
for (const content of batch) {
|
|
180
|
+
broker.publish('execution', 'execute.start', content);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
316
183
|
|
|
317
|
-
|
|
318
|
-
|
|
184
|
+
ParallelLoopCharacteristics.prototype._onCompleteMessage = function onCompleteMessage(_, message) {
|
|
185
|
+
const chr = this.characteristics;
|
|
186
|
+
const {
|
|
187
|
+
content
|
|
188
|
+
} = message;
|
|
189
|
+
if (content.output !== undefined) chr.output[content.index] = content.output;
|
|
190
|
+
this.running--;
|
|
191
|
+
this.activity.broker.publish('execution', 'execute.iteration.completed', { ...content,
|
|
192
|
+
...chr.getContent(),
|
|
193
|
+
index: this.index,
|
|
194
|
+
running: this.running,
|
|
195
|
+
output: chr.output,
|
|
196
|
+
state: 'iteration.completed',
|
|
197
|
+
preventComplete: true
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
if (this.running <= 0 && !chr.next(this.index)) {
|
|
201
|
+
return chr.complete(content);
|
|
202
|
+
}
|
|
319
203
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
204
|
+
if (chr.isCompletionConditionMet(message)) {
|
|
205
|
+
return chr.complete(content);
|
|
206
|
+
}
|
|
323
207
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
return Number(value);
|
|
327
|
-
}
|
|
208
|
+
if (this.running <= 0) {
|
|
209
|
+
this.running = 0;
|
|
328
210
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
211
|
+
this._startBatch();
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
function Characteristics(activity, loopCharacteristics, executeMessage) {
|
|
216
|
+
this.activity = activity;
|
|
217
|
+
const behaviour = this.behaviour = loopCharacteristics.behaviour || {};
|
|
218
|
+
this.message = executeMessage;
|
|
219
|
+
const type = this.type = loopCharacteristics.type || 'LoopCharacteristics';
|
|
220
|
+
this.id = activity.id;
|
|
221
|
+
this.broker = activity.broker;
|
|
222
|
+
this.parentExecutionId = executeMessage.content.executionId;
|
|
223
|
+
this.isSequential = behaviour.isSequential || false;
|
|
224
|
+
this.output = executeMessage.content.output || [];
|
|
225
|
+
this.parent = (0, _messageHelper.unshiftParent)(executeMessage.content.parent, executeMessage.content);
|
|
226
|
+
if ('loopCardinality' in behaviour) this.loopCardinality = behaviour.loopCardinality;else if ('loopMaximum' in behaviour) this.loopCardinality = behaviour.loopMaximum;
|
|
334
227
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
noAck: true,
|
|
338
|
-
consumerTag: apiConsumerTag
|
|
339
|
-
}, {
|
|
340
|
-
priority: 400
|
|
341
|
-
});
|
|
342
|
-
broker.subscribeTmp('execution', 'execute.*', onComplete, {
|
|
343
|
-
noAck: true,
|
|
344
|
-
consumerTag: executeConsumerTag,
|
|
345
|
-
priority: 300
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
function onComplete(routingKey, message, ...args) {
|
|
349
|
-
if (!message.content.isMultiInstance) return;
|
|
350
|
-
|
|
351
|
-
switch (routingKey) {
|
|
352
|
-
case 'execute.cancel':
|
|
353
|
-
case 'execute.completed':
|
|
354
|
-
return onIterationCompleteMessage(routingKey, message, ...args);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
228
|
+
if (behaviour.loopCondition) {
|
|
229
|
+
if (behaviour.testBefore) this.startCondition = behaviour.loopCondition;else this.completionCondition = behaviour.loopCondition;
|
|
358
230
|
}
|
|
359
231
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
232
|
+
if (behaviour.completionCondition) {
|
|
233
|
+
this.completionCondition = behaviour.completionCondition;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const collection = this.collection = this.getCollection();
|
|
237
|
+
|
|
238
|
+
if (collection) {
|
|
239
|
+
this.elementVariable = behaviour.elementVariable || 'item';
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
this.cardinality = this.getCardinality(collection);
|
|
243
|
+
this.onApiMessage = this.onApiMessage.bind(this);
|
|
244
|
+
const environment = activity.environment;
|
|
245
|
+
this.logger = environment.Logger(type.toLowerCase());
|
|
246
|
+
this.batchSize = environment.settings.batchSize || 50;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
Characteristics.prototype.getContent = function getContent() {
|
|
250
|
+
return { ...(0, _messageHelper.cloneContent)(this.message.content),
|
|
251
|
+
loopCardinality: this.cardinality,
|
|
252
|
+
isSequential: this.isSequential,
|
|
253
|
+
output: undefined
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
Characteristics.prototype.next = function next(index) {
|
|
258
|
+
const cardinality = this.cardinality;
|
|
259
|
+
if (cardinality > 0 && index >= cardinality) return;
|
|
260
|
+
const collection = this.collection;
|
|
261
|
+
if (collection && index >= collection.length) return;
|
|
262
|
+
const content = { ...this.getContent(),
|
|
263
|
+
isRootScope: undefined,
|
|
264
|
+
executionId: `${this.parentExecutionId}_${index}`,
|
|
265
|
+
isMultiInstance: true,
|
|
266
|
+
parent: (0, _messageHelper.cloneParent)(this.parent),
|
|
267
|
+
index
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
if (collection) {
|
|
271
|
+
content[this.elementVariable] = collection[index];
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return content;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
Characteristics.prototype.getCardinality = function getCardinality(collection) {
|
|
278
|
+
const collectionLen = this.collection && Array.isArray(collection) ? collection.length : undefined;
|
|
279
|
+
|
|
280
|
+
if (!this.loopCardinality) {
|
|
281
|
+
return collectionLen;
|
|
367
282
|
}
|
|
368
283
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
284
|
+
const value = this.activity.environment.resolveExpression(this.loopCardinality, this.message);
|
|
285
|
+
|
|
286
|
+
if (value !== undefined && isNaN(value) || value < 0) {
|
|
287
|
+
throw new _Errors.RunError(`<${this.id}> invalid loop cardinality >${value}<`, this.message);
|
|
372
288
|
}
|
|
373
289
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
290
|
+
if (value === undefined) return collectionLen;
|
|
291
|
+
return Number(value);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
Characteristics.prototype.getCollection = function getCollection() {
|
|
295
|
+
const collectionExpression = this.behaviour.collection;
|
|
296
|
+
if (!collectionExpression) return;
|
|
297
|
+
return this.activity.environment.resolveExpression(collectionExpression, this.message);
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
Characteristics.prototype.isStartConditionMet = function isStartConditionMet(message) {
|
|
301
|
+
if (!this.startCondition) return false;
|
|
302
|
+
return this.activity.environment.resolveExpression(this.startCondition, (0, _messageHelper.cloneMessage)(message));
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
Characteristics.prototype.isCompletionConditionMet = function isCompletionConditionMet(message) {
|
|
306
|
+
if (!this.completionCondition) return false;
|
|
307
|
+
return this.activity.environment.resolveExpression(this.completionCondition, (0, _messageHelper.cloneMessage)(message, {
|
|
308
|
+
loopOutput: this.output
|
|
309
|
+
}));
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
Characteristics.prototype.complete = function complete(content) {
|
|
313
|
+
this.stop();
|
|
314
|
+
return this.broker.publish('execution', 'execute.completed', { ...content,
|
|
315
|
+
...this.getContent(),
|
|
316
|
+
output: this.output
|
|
317
|
+
});
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
Characteristics.prototype.subscribe = function subscribe(onIterationCompleteMessage) {
|
|
321
|
+
this.broker.subscribeTmp('api', `activity.*.${this.parentExecutionId}`, this.onApiMessage, {
|
|
322
|
+
noAck: true,
|
|
323
|
+
consumerTag: '_api-multi-instance-tag'
|
|
324
|
+
}, {
|
|
325
|
+
priority: 400
|
|
326
|
+
});
|
|
327
|
+
this.broker.subscribeTmp('execution', 'execute.*', onComplete, {
|
|
328
|
+
noAck: true,
|
|
329
|
+
consumerTag: '_execute-q-multi-instance-tag',
|
|
330
|
+
priority: 300
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
function onComplete(routingKey, message, ...args) {
|
|
334
|
+
if (!message.content.isMultiInstance) return;
|
|
335
|
+
|
|
336
|
+
switch (routingKey) {
|
|
337
|
+
case 'execute.cancel':
|
|
338
|
+
case 'execute.completed':
|
|
339
|
+
return onIterationCompleteMessage(routingKey, message, ...args);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
Characteristics.prototype.onApiMessage = function onApiMessage(_, message) {
|
|
345
|
+
switch (message.properties.type) {
|
|
346
|
+
case 'stop':
|
|
347
|
+
case 'discard':
|
|
348
|
+
this.stop();
|
|
349
|
+
break;
|
|
380
350
|
}
|
|
381
|
-
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
Characteristics.prototype.stop = function stop() {
|
|
354
|
+
this.broker.cancel('_execute-q-multi-instance-tag');
|
|
355
|
+
this.broker.cancel('_api-multi-instance-tag');
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
Characteristics.prototype.debug = function debug(msg) {
|
|
359
|
+
this.logger.debug(`<${this.parentExecutionId} (${this.id})> ${msg}`);
|
|
360
|
+
};
|