bpmn-elements 17.3.0 → 18.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/README.md +3 -1
- package/dist/Api.js +83 -0
- package/dist/Context.js +228 -22
- package/dist/Environment.js +111 -31
- package/dist/EventBroker.js +57 -1
- package/dist/Expressions.js +3 -4
- package/dist/MessageFormatter.js +29 -16
- package/dist/Timers.js +13 -9
- package/dist/Tracker.js +1 -0
- package/dist/activity/Activity.js +434 -233
- package/dist/activity/ActivityExecution.js +113 -40
- package/dist/activity/Dummy.js +6 -1
- package/dist/activity/Escalation.js +36 -24
- package/dist/activity/ExecutionScope.js +1 -1
- package/dist/activity/Message.js +36 -24
- package/dist/activity/Signal.js +36 -24
- package/dist/activity/outbound-evaluator.js +1 -1
- package/dist/condition.js +12 -6
- package/dist/constants.js +27 -0
- package/dist/definition/Definition.js +187 -64
- package/dist/definition/DefinitionExecution.js +198 -84
- package/dist/error/BpmnError.js +12 -1
- package/dist/error/Errors.js +50 -9
- package/dist/eventDefinitions/CancelEventDefinition.js +29 -11
- package/dist/eventDefinitions/CompensateEventDefinition.js +51 -31
- package/dist/eventDefinitions/ConditionalEventDefinition.js +21 -9
- package/dist/eventDefinitions/ErrorEventDefinition.js +46 -30
- package/dist/eventDefinitions/EscalationEventDefinition.js +44 -27
- package/dist/eventDefinitions/EventDefinitionExecution.js +30 -23
- package/dist/eventDefinitions/LinkEventDefinition.js +45 -120
- package/dist/eventDefinitions/MessageEventDefinition.js +44 -29
- package/dist/eventDefinitions/SignalEventDefinition.js +46 -31
- package/dist/eventDefinitions/TerminateEventDefinition.js +10 -1
- package/dist/eventDefinitions/TimerEventDefinition.js +57 -37
- package/dist/eventDefinitions/index.js +20 -21
- package/dist/events/BoundaryEvent.js +52 -40
- package/dist/events/EndEvent.js +22 -8
- package/dist/events/IntermediateCatchEvent.js +26 -8
- package/dist/events/IntermediateThrowEvent.js +24 -9
- package/dist/events/StartEvent.js +30 -14
- package/dist/events/index.js +10 -11
- package/dist/flows/Association.js +50 -7
- package/dist/flows/MessageFlow.js +49 -10
- package/dist/flows/SequenceFlow.js +93 -22
- package/dist/flows/index.js +6 -7
- package/dist/gateways/EventBasedGateway.js +29 -15
- package/dist/gateways/ExclusiveGateway.js +20 -5
- package/dist/gateways/InclusiveGateway.js +21 -5
- package/dist/gateways/ParallelGateway.js +253 -15
- package/dist/gateways/index.js +8 -9
- package/dist/getPropertyValue.js +1 -1
- package/dist/index.js +42 -43
- package/dist/io/BpmnIO.js +15 -1
- package/dist/io/EnvironmentDataObject.js +29 -1
- package/dist/io/EnvironmentDataStore.js +24 -1
- package/dist/io/EnvironmentDataStoreReference.js +24 -1
- package/dist/io/InputOutputSpecification.js +21 -11
- package/dist/io/Properties.js +28 -17
- package/dist/messageHelper.js +41 -4
- package/dist/process/Lane.js +15 -4
- package/dist/process/Process.js +176 -77
- package/dist/process/ProcessExecution.js +397 -178
- package/dist/shared.js +2 -0
- package/dist/tasks/CallActivity.js +19 -4
- package/dist/tasks/LoopCharacteristics.js +94 -9
- package/dist/tasks/ReceiveTask.js +36 -21
- package/dist/tasks/ScriptTask.js +22 -6
- package/dist/tasks/ServiceImplementation.js +7 -4
- package/dist/tasks/ServiceTask.js +19 -4
- package/dist/tasks/SignalTask.js +19 -4
- package/dist/tasks/StandardLoopCharacteristics.js +8 -4
- package/dist/tasks/SubProcess.js +44 -29
- package/dist/tasks/Task.js +19 -4
- package/dist/tasks/Transaction.js +8 -4
- package/dist/tasks/index.js +16 -18
- package/package.json +31 -13
- package/src/Api.js +70 -0
- package/src/Context.js +200 -19
- package/src/Environment.js +99 -30
- package/src/EventBroker.js +46 -1
- package/src/Expressions.js +2 -3
- package/src/MessageFormatter.js +24 -16
- package/src/Timers.js +12 -9
- package/src/Tracker.js +1 -0
- package/src/activity/Activity.js +372 -218
- package/src/activity/ActivityExecution.js +93 -42
- package/src/activity/Dummy.js +6 -1
- package/src/activity/Escalation.js +25 -18
- package/src/activity/ExecutionScope.js +1 -1
- package/src/activity/Message.js +25 -18
- package/src/activity/Signal.js +25 -18
- package/src/activity/outbound-evaluator.js +1 -1
- package/src/condition.js +11 -5
- package/src/constants.js +21 -0
- package/src/definition/Definition.js +165 -63
- package/src/definition/DefinitionExecution.js +164 -85
- package/src/error/BpmnError.js +11 -1
- package/src/error/Errors.js +44 -5
- package/src/eventDefinitions/CancelEventDefinition.js +27 -13
- package/src/eventDefinitions/CompensateEventDefinition.js +48 -32
- package/src/eventDefinitions/ConditionalEventDefinition.js +20 -10
- package/src/eventDefinitions/ErrorEventDefinition.js +44 -33
- package/src/eventDefinitions/EscalationEventDefinition.js +39 -26
- package/src/eventDefinitions/EventDefinitionExecution.js +30 -24
- package/src/eventDefinitions/LinkEventDefinition.js +34 -120
- package/src/eventDefinitions/MessageEventDefinition.js +42 -31
- package/src/eventDefinitions/SignalEventDefinition.js +43 -32
- package/src/eventDefinitions/TerminateEventDefinition.js +9 -1
- package/src/eventDefinitions/TimerEventDefinition.js +53 -35
- package/src/eventDefinitions/index.js +10 -23
- package/src/events/BoundaryEvent.js +50 -39
- package/src/events/EndEvent.js +19 -7
- package/src/events/IntermediateCatchEvent.js +24 -8
- package/src/events/IntermediateThrowEvent.js +24 -8
- package/src/events/StartEvent.js +25 -14
- package/src/events/index.js +5 -18
- package/src/flows/Association.js +43 -9
- package/src/flows/MessageFlow.js +41 -10
- package/src/flows/SequenceFlow.js +82 -19
- package/src/flows/index.js +3 -4
- package/src/gateways/EventBasedGateway.js +27 -15
- package/src/gateways/ExclusiveGateway.js +16 -3
- package/src/gateways/InclusiveGateway.js +16 -3
- package/src/gateways/ParallelGateway.js +301 -10
- package/src/gateways/index.js +4 -4
- package/src/getPropertyValue.js +1 -1
- package/src/index.js +19 -19
- package/src/io/BpmnIO.js +13 -1
- package/src/io/EnvironmentDataObject.js +26 -1
- package/src/io/EnvironmentDataStore.js +22 -1
- package/src/io/EnvironmentDataStoreReference.js +22 -1
- package/src/io/InputOutputSpecification.js +17 -8
- package/src/io/Properties.js +23 -13
- package/src/messageHelper.js +36 -4
- package/src/process/Lane.js +14 -4
- package/src/process/Process.js +157 -74
- package/src/process/ProcessExecution.js +363 -176
- package/src/shared.js +1 -0
- package/src/tasks/CallActivity.js +16 -2
- package/src/tasks/LoopCharacteristics.js +77 -11
- package/src/tasks/ReceiveTask.js +33 -22
- package/src/tasks/ScriptTask.js +17 -3
- package/src/tasks/ServiceImplementation.js +6 -3
- package/src/tasks/ServiceTask.js +16 -2
- package/src/tasks/SignalTask.js +16 -2
- package/src/tasks/StandardLoopCharacteristics.js +7 -3
- package/src/tasks/SubProcess.js +37 -23
- package/src/tasks/Task.js +16 -2
- package/src/tasks/Transaction.js +7 -3
- package/src/tasks/index.js +8 -9
- package/types/bundle-errors.d.ts +1 -0
- package/types/bundle.d.ts +97 -0
- package/types/index.d.ts +2619 -84
- package/types/interfaces.d.ts +638 -0
- package/types/types.d.ts +0 -765
|
@@ -3,22 +3,25 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.ProcessExecution = ProcessExecution;
|
|
7
7
|
var _Api = require("../Api.js");
|
|
8
8
|
var _messageHelper = require("../messageHelper.js");
|
|
9
9
|
var _shared = require("../shared.js");
|
|
10
10
|
var _Tracker = require("../Tracker.js");
|
|
11
|
-
var
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
var _constants = require("../constants.js");
|
|
12
|
+
const K_ACTIVITY_Q = Symbol.for('activityQ');
|
|
13
|
+
const K_ELEMENTS = Symbol.for('elements');
|
|
14
|
+
const K_PARENT = Symbol.for('parent');
|
|
15
|
+
const K_TRACKER = Symbol.for('activity tracker');
|
|
16
|
+
const K_PEERS_DISCOVERED = Symbol.for('peers discovered');
|
|
17
|
+
const K_RECOVERED_VERSION = Symbol.for('recovered version');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Drives the execution of a single process or sub-process: activates children, routes activity
|
|
21
|
+
* events, and rolls completion up to the owning Process or sub-process Activity.
|
|
22
|
+
* @param {import('#types').Process | import('#types').Activity} parentActivity
|
|
23
|
+
* @param {import('#types').ContextInstance} context
|
|
24
|
+
*/
|
|
22
25
|
function ProcessExecution(parentActivity, context) {
|
|
23
26
|
const {
|
|
24
27
|
id,
|
|
@@ -27,7 +30,7 @@ function ProcessExecution(parentActivity, context) {
|
|
|
27
30
|
isSubProcess,
|
|
28
31
|
isTransaction
|
|
29
32
|
} = parentActivity;
|
|
30
|
-
this[
|
|
33
|
+
this[K_PARENT] = parentActivity;
|
|
31
34
|
this.id = id;
|
|
32
35
|
this.type = type;
|
|
33
36
|
this.isSubProcess = isSubProcess;
|
|
@@ -35,29 +38,30 @@ function ProcessExecution(parentActivity, context) {
|
|
|
35
38
|
this.broker = broker;
|
|
36
39
|
this.environment = context.environment;
|
|
37
40
|
this.context = context;
|
|
38
|
-
this[
|
|
41
|
+
this[K_ELEMENTS] = {
|
|
39
42
|
postponed: new Set(),
|
|
40
43
|
children: context.getActivities(id),
|
|
41
44
|
associations: context.getAssociations(id),
|
|
42
45
|
flows: context.getSequenceFlows(id),
|
|
43
46
|
outboundMessageFlows: context.getMessageFlows(id),
|
|
44
47
|
startActivities: new Set(),
|
|
48
|
+
startEventCount: 0,
|
|
45
49
|
triggeredByEvent: new Set(),
|
|
46
50
|
detachedActivities: new Set(),
|
|
47
|
-
|
|
51
|
+
convergingGateways: new Set()
|
|
48
52
|
};
|
|
49
53
|
const exchangeName = this._exchangeName = isSubProcess ? 'subprocess-execution' : 'execution';
|
|
50
54
|
broker.assertExchange(exchangeName, 'topic', {
|
|
51
55
|
autoDelete: false,
|
|
52
56
|
durable: true
|
|
53
57
|
});
|
|
54
|
-
this[
|
|
55
|
-
this[
|
|
56
|
-
this[
|
|
57
|
-
this[
|
|
58
|
-
this[
|
|
58
|
+
this[_constants.K_COMPLETED] = false;
|
|
59
|
+
this[_constants.K_STOPPED] = false;
|
|
60
|
+
this[_constants.K_ACTIVATED] = false;
|
|
61
|
+
this[_constants.K_STATUS] = 'init';
|
|
62
|
+
this[K_TRACKER] = new _Tracker.ActivityTracker(id);
|
|
59
63
|
this.executionId = undefined;
|
|
60
|
-
this[
|
|
64
|
+
this[_constants.K_MESSAGE_HANDLERS] = {
|
|
61
65
|
onActivityEvent: this._onActivityEvent.bind(this),
|
|
62
66
|
onApiMessage: this._onApiMessage.bind(this),
|
|
63
67
|
onChildMessage: this._onChildMessage.bind(this),
|
|
@@ -67,46 +71,52 @@ function ProcessExecution(parentActivity, context) {
|
|
|
67
71
|
Object.defineProperties(ProcessExecution.prototype, {
|
|
68
72
|
stopped: {
|
|
69
73
|
get() {
|
|
70
|
-
return this[
|
|
74
|
+
return this[_constants.K_STOPPED];
|
|
71
75
|
}
|
|
72
76
|
},
|
|
73
77
|
completed: {
|
|
74
78
|
get() {
|
|
75
|
-
return this[
|
|
79
|
+
return this[_constants.K_COMPLETED];
|
|
76
80
|
}
|
|
77
81
|
},
|
|
78
82
|
status: {
|
|
79
83
|
get() {
|
|
80
|
-
return this[
|
|
84
|
+
return this[_constants.K_STATUS];
|
|
81
85
|
}
|
|
82
86
|
},
|
|
83
87
|
postponedCount: {
|
|
84
88
|
get() {
|
|
85
|
-
return this[
|
|
89
|
+
return this[K_ELEMENTS].postponed.size;
|
|
86
90
|
}
|
|
87
91
|
},
|
|
88
92
|
isRunning: {
|
|
89
93
|
get() {
|
|
90
|
-
return this[
|
|
94
|
+
return this[_constants.K_ACTIVATED];
|
|
91
95
|
}
|
|
92
96
|
},
|
|
93
97
|
activityStatus: {
|
|
94
98
|
get() {
|
|
95
|
-
return this[
|
|
99
|
+
return this[K_TRACKER].activityStatus;
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
});
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Activate children and start the process execution. Resumes if the message is redelivered.
|
|
106
|
+
* @param {import('#types').ElementBrokerMessage} executeMessage
|
|
107
|
+
* @throws {Error} when message or executionId is missing
|
|
108
|
+
*/
|
|
99
109
|
ProcessExecution.prototype.execute = function execute(executeMessage) {
|
|
100
110
|
if (!executeMessage) throw new Error('Process execution requires message');
|
|
101
111
|
if (!executeMessage.content || !executeMessage.content.executionId) throw new Error('Process execution requires execution id');
|
|
102
112
|
const executionId = this.executionId = executeMessage.content.executionId;
|
|
103
|
-
this[
|
|
113
|
+
this[_constants.K_EXECUTE_MESSAGE] = (0, _messageHelper.cloneMessage)(executeMessage, {
|
|
104
114
|
executionId,
|
|
105
115
|
state: 'start'
|
|
106
116
|
});
|
|
107
|
-
this[
|
|
117
|
+
this[_constants.K_STOPPED] = false;
|
|
108
118
|
this.environment.assignVariables(executeMessage);
|
|
109
|
-
this[
|
|
119
|
+
this[K_ACTIVITY_Q] = this.broker.assertQueue(`execute-${executionId}-q`, {
|
|
110
120
|
durable: true,
|
|
111
121
|
autoDelete: false
|
|
112
122
|
});
|
|
@@ -118,28 +128,29 @@ ProcessExecution.prototype.execute = function execute(executeMessage) {
|
|
|
118
128
|
this._start();
|
|
119
129
|
return true;
|
|
120
130
|
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Resume after recover, resuming any postponed children.
|
|
134
|
+
*/
|
|
121
135
|
ProcessExecution.prototype.resume = function resume() {
|
|
122
136
|
this._debug(`resume process execution at ${this.status}`);
|
|
123
|
-
if (this[
|
|
137
|
+
if (this[_constants.K_COMPLETED]) return this._complete('completed');
|
|
124
138
|
this._activate();
|
|
125
139
|
const {
|
|
126
|
-
|
|
127
|
-
detachedActivities
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (startActivities.size > 1) {
|
|
131
|
-
for (const a of startActivities) a.shake();
|
|
132
|
-
}
|
|
140
|
+
postponed,
|
|
141
|
+
detachedActivities
|
|
142
|
+
} = this[K_ELEMENTS];
|
|
143
|
+
this._shakeOnStart();
|
|
133
144
|
postponed.clear();
|
|
134
145
|
detachedActivities.clear();
|
|
135
|
-
this[
|
|
146
|
+
this[K_ACTIVITY_Q].consume(this[_constants.K_MESSAGE_HANDLERS].onChildMessage, {
|
|
136
147
|
prefetch: 1000,
|
|
137
148
|
consumerTag: `_process-activity-${this.executionId}`
|
|
138
149
|
});
|
|
139
|
-
if (this[
|
|
150
|
+
if (this[_constants.K_COMPLETED]) return;
|
|
140
151
|
const status = this.status;
|
|
141
152
|
if (status === 'init') return this._start();
|
|
142
|
-
const tracker = this[
|
|
153
|
+
const tracker = this[K_TRACKER];
|
|
143
154
|
for (const msg of new Set(postponed)) {
|
|
144
155
|
const activity = this.getActivityById(msg.content.id);
|
|
145
156
|
if (!activity) continue;
|
|
@@ -152,16 +163,23 @@ ProcessExecution.prototype.resume = function resume() {
|
|
|
152
163
|
tracker.track(msg.fields.routingKey, msg);
|
|
153
164
|
activity.resume();
|
|
154
165
|
}
|
|
155
|
-
if (this[
|
|
166
|
+
if (this[_constants.K_COMPLETED]) return;
|
|
167
|
+
this._reconcileStartEvents();
|
|
168
|
+
if (this[_constants.K_COMPLETED]) return;
|
|
156
169
|
if (!postponed.size && status === 'executing') return this._complete('completed');
|
|
157
170
|
};
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Snapshot execution state including children, flows, message flows, and associations.
|
|
174
|
+
* @returns {import('#types').ProcessExecutionState}
|
|
175
|
+
*/
|
|
158
176
|
ProcessExecution.prototype.getState = function getState() {
|
|
159
177
|
const {
|
|
160
178
|
children,
|
|
161
179
|
flows,
|
|
162
180
|
outboundMessageFlows,
|
|
163
181
|
associations
|
|
164
|
-
} = this[
|
|
182
|
+
} = this[K_ELEMENTS];
|
|
165
183
|
const flowStates = flows.reduce((result, flow) => {
|
|
166
184
|
const elmState = flow.getState();
|
|
167
185
|
if (elmState) result.push(elmState);
|
|
@@ -169,8 +187,8 @@ ProcessExecution.prototype.getState = function getState() {
|
|
|
169
187
|
}, []);
|
|
170
188
|
return {
|
|
171
189
|
executionId: this.executionId,
|
|
172
|
-
stopped: this[
|
|
173
|
-
completed: this[
|
|
190
|
+
stopped: this[_constants.K_STOPPED],
|
|
191
|
+
completed: this[_constants.K_COMPLETED],
|
|
174
192
|
status: this.status,
|
|
175
193
|
children: children.reduce((result, activity) => {
|
|
176
194
|
if (activity.placeholder) return result;
|
|
@@ -189,12 +207,20 @@ ProcessExecution.prototype.getState = function getState() {
|
|
|
189
207
|
})
|
|
190
208
|
};
|
|
191
209
|
};
|
|
192
|
-
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Restore execution state captured by getState.
|
|
213
|
+
* @param {import('#types').ProcessExecutionState} [state]
|
|
214
|
+
* @param {number} [recoveredVersion] State version
|
|
215
|
+
* @returns {this}
|
|
216
|
+
*/
|
|
217
|
+
ProcessExecution.prototype.recover = function recover(state, recoveredVersion) {
|
|
193
218
|
if (!state) return this;
|
|
194
219
|
this.executionId = state.executionId;
|
|
195
|
-
this[
|
|
196
|
-
this[
|
|
197
|
-
this[
|
|
220
|
+
this[K_RECOVERED_VERSION] = recoveredVersion;
|
|
221
|
+
this[_constants.K_STOPPED] = state.stopped;
|
|
222
|
+
this[_constants.K_COMPLETED] = state.completed;
|
|
223
|
+
this[_constants.K_STATUS] = state.status;
|
|
198
224
|
this._debug(`recover process execution at ${this.status}`);
|
|
199
225
|
if (state.messageFlows) {
|
|
200
226
|
for (const flowState of state.messageFlows) {
|
|
@@ -226,53 +252,30 @@ ProcessExecution.prototype.recover = function recover(state) {
|
|
|
226
252
|
}
|
|
227
253
|
return this;
|
|
228
254
|
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Walk activity graph from the given start id, or every start activity when omitted.
|
|
258
|
+
* @param {string} [fromId]
|
|
259
|
+
* @returns {import('#types').ShakeResult}
|
|
260
|
+
*/
|
|
229
261
|
ProcessExecution.prototype.shake = function shake(fromId) {
|
|
230
|
-
|
|
231
|
-
const id = this.id;
|
|
232
|
-
if (!this.isRunning) {
|
|
233
|
-
executing = false;
|
|
234
|
-
this.executionId = (0, _shared.getUniqueId)(id);
|
|
235
|
-
this._activate();
|
|
236
|
-
}
|
|
237
|
-
const toShake = fromId ? [this.getActivityById(fromId)].filter(Boolean) : this[kElements].startActivities;
|
|
238
|
-
const result = {};
|
|
239
|
-
this.broker.subscribeTmp('event', '*.shake.*', (routingKey, {
|
|
240
|
-
content
|
|
241
|
-
}) => {
|
|
242
|
-
let isLooped = false;
|
|
243
|
-
switch (routingKey) {
|
|
244
|
-
case 'flow.shake.loop':
|
|
245
|
-
isLooped = true;
|
|
246
|
-
case 'activity.shake.end':
|
|
247
|
-
{
|
|
248
|
-
const {
|
|
249
|
-
id: shakeId,
|
|
250
|
-
parent: shakeParent
|
|
251
|
-
} = content;
|
|
252
|
-
if (shakeParent.id !== id) return;
|
|
253
|
-
result[shakeId] = result[shakeId] || [];
|
|
254
|
-
result[shakeId].push({
|
|
255
|
-
...content,
|
|
256
|
-
isLooped
|
|
257
|
-
});
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}, {
|
|
262
|
-
noAck: true,
|
|
263
|
-
consumerTag: `_shaker-${this.executionId}`
|
|
264
|
-
});
|
|
265
|
-
for (const a of toShake) a.shake();
|
|
266
|
-
if (!executing) this._deactivate();
|
|
267
|
-
this.broker.cancel(`_shaker-${this.executionId}`);
|
|
268
|
-
return result;
|
|
262
|
+
return Object.fromEntries(this._shakeElements(fromId).sequences);
|
|
269
263
|
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Stop the running process execution via the api.
|
|
267
|
+
*/
|
|
270
268
|
ProcessExecution.prototype.stop = function stop() {
|
|
271
269
|
this.getApi().stop();
|
|
272
270
|
};
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* List currently postponed children as Api wrappers.
|
|
274
|
+
* @param {import('#types').filterPostponed} [filterFn]
|
|
275
|
+
*/
|
|
273
276
|
ProcessExecution.prototype.getPostponed = function getPostponed(filterFn) {
|
|
274
277
|
const result = [];
|
|
275
|
-
for (const msg of this[
|
|
278
|
+
for (const msg of this[K_ELEMENTS].postponed) {
|
|
276
279
|
const api = this._getChildApi(msg);
|
|
277
280
|
if (!api) continue;
|
|
278
281
|
if (filterFn && !filterFn(api)) continue;
|
|
@@ -280,9 +283,13 @@ ProcessExecution.prototype.getPostponed = function getPostponed(filterFn) {
|
|
|
280
283
|
}
|
|
281
284
|
return result;
|
|
282
285
|
};
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Queue a discard message that propagates to all running children.
|
|
289
|
+
*/
|
|
283
290
|
ProcessExecution.prototype.discard = function discard() {
|
|
284
|
-
this[
|
|
285
|
-
|
|
291
|
+
this[_constants.K_STATUS] = 'discard';
|
|
292
|
+
this[K_ACTIVITY_Q].queueMessage({
|
|
286
293
|
routingKey: 'execution.discard'
|
|
287
294
|
}, {
|
|
288
295
|
id: this.id,
|
|
@@ -292,8 +299,12 @@ ProcessExecution.prototype.discard = function discard() {
|
|
|
292
299
|
type: 'discard'
|
|
293
300
|
});
|
|
294
301
|
};
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Queue a cancel message that propagates to all running children.
|
|
305
|
+
*/
|
|
295
306
|
ProcessExecution.prototype.cancel = function discard() {
|
|
296
|
-
|
|
307
|
+
this[K_ACTIVITY_Q].queueMessage({
|
|
297
308
|
routingKey: 'execution.cancel'
|
|
298
309
|
}, {
|
|
299
310
|
id: this.id,
|
|
@@ -303,26 +314,52 @@ ProcessExecution.prototype.cancel = function discard() {
|
|
|
303
314
|
type: 'cancel'
|
|
304
315
|
});
|
|
305
316
|
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Get child activities in the process scope.
|
|
320
|
+
* @returns {import('#types').Activity[]}
|
|
321
|
+
*/
|
|
306
322
|
ProcessExecution.prototype.getActivities = function getActivities() {
|
|
307
|
-
return this[
|
|
323
|
+
return this[K_ELEMENTS].children.slice();
|
|
308
324
|
};
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* @param {string} activityId
|
|
328
|
+
* @returns {import('#types').Activity}
|
|
329
|
+
*/
|
|
309
330
|
ProcessExecution.prototype.getActivityById = function getActivityById(activityId) {
|
|
310
|
-
return this[
|
|
331
|
+
return this[K_ELEMENTS].children.find(child => child.id === activityId);
|
|
311
332
|
};
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Get sequence flows in the process scope.
|
|
336
|
+
* @returns {import('#types').SequenceFlow}
|
|
337
|
+
*/
|
|
312
338
|
ProcessExecution.prototype.getSequenceFlows = function getSequenceFlows() {
|
|
313
|
-
return this[
|
|
339
|
+
return this[K_ELEMENTS].flows.slice();
|
|
314
340
|
};
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get associations in the process scope.
|
|
344
|
+
* @returns {import('../flows/Association.js').Association}
|
|
345
|
+
*/
|
|
315
346
|
ProcessExecution.prototype.getAssociations = function getAssociations() {
|
|
316
|
-
return this[
|
|
347
|
+
return this[K_ELEMENTS].associations.slice();
|
|
317
348
|
};
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Resolve a process or child Api for the given message.
|
|
352
|
+
* @param {import('#types').ElementBrokerMessage} [message]
|
|
353
|
+
* @returns {import('#types').IApi<import('#types').Process>}
|
|
354
|
+
*/
|
|
318
355
|
ProcessExecution.prototype.getApi = function getApi(message) {
|
|
319
|
-
if (!message) return (0, _Api.ProcessApi)(this.broker, this[
|
|
356
|
+
if (!message) return (0, _Api.ProcessApi)(this.broker, this[_constants.K_EXECUTE_MESSAGE]);
|
|
320
357
|
const content = message.content;
|
|
321
358
|
if (content.executionId !== this.executionId) {
|
|
322
359
|
return this._getChildApi(message);
|
|
323
360
|
}
|
|
324
361
|
const api = (0, _Api.ProcessApi)(this.broker, message);
|
|
325
|
-
const postponed = this[
|
|
362
|
+
const postponed = this[K_ELEMENTS].postponed;
|
|
326
363
|
const self = this;
|
|
327
364
|
api.getExecuting = function getExecuting() {
|
|
328
365
|
const result = [];
|
|
@@ -334,13 +371,15 @@ ProcessExecution.prototype.getApi = function getApi(message) {
|
|
|
334
371
|
};
|
|
335
372
|
return api;
|
|
336
373
|
};
|
|
374
|
+
|
|
375
|
+
/** @internal */
|
|
337
376
|
ProcessExecution.prototype._start = function start() {
|
|
338
|
-
if (!this[
|
|
377
|
+
if (!this[K_ELEMENTS].children.length) {
|
|
339
378
|
return this._complete('completed');
|
|
340
379
|
}
|
|
341
|
-
this[
|
|
380
|
+
this[_constants.K_STATUS] = 'start';
|
|
342
381
|
const executeContent = {
|
|
343
|
-
...this[
|
|
382
|
+
...this[_constants.K_EXECUTE_MESSAGE].content,
|
|
344
383
|
state: this.status
|
|
345
384
|
};
|
|
346
385
|
this.broker.publish(this._exchangeName, 'execute.start', (0, _messageHelper.cloneContent)(executeContent));
|
|
@@ -348,26 +387,31 @@ ProcessExecution.prototype._start = function start() {
|
|
|
348
387
|
startActivities,
|
|
349
388
|
postponed,
|
|
350
389
|
detachedActivities
|
|
351
|
-
} = this[
|
|
352
|
-
|
|
353
|
-
for (const a of startActivities) a.shake();
|
|
354
|
-
}
|
|
390
|
+
} = this[K_ELEMENTS];
|
|
391
|
+
this._shakeOnStart();
|
|
355
392
|
for (const a of startActivities) a.init();
|
|
356
|
-
this[
|
|
393
|
+
this[_constants.K_STATUS] = 'executing';
|
|
357
394
|
for (const a of startActivities) a.run();
|
|
395
|
+
if (!startActivities.size) {
|
|
396
|
+
for (const a of this[K_ELEMENTS].triggeredByEvent) {
|
|
397
|
+
if (a.isCatching && !a.isRunning) a.run();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
358
400
|
postponed.clear();
|
|
359
401
|
detachedActivities.clear();
|
|
360
|
-
this[
|
|
402
|
+
this[K_ACTIVITY_Q].assertConsumer(this[_constants.K_MESSAGE_HANDLERS].onChildMessage, {
|
|
361
403
|
prefetch: 1000,
|
|
362
404
|
consumerTag: `_process-activity-${this.executionId}`
|
|
363
405
|
});
|
|
364
406
|
};
|
|
407
|
+
|
|
408
|
+
/** @internal */
|
|
365
409
|
ProcessExecution.prototype._activate = function activate() {
|
|
366
410
|
const {
|
|
367
411
|
onApiMessage,
|
|
368
412
|
onMessageFlowEvent,
|
|
369
413
|
onActivityEvent
|
|
370
|
-
} = this[
|
|
414
|
+
} = this[_constants.K_MESSAGE_HANDLERS];
|
|
371
415
|
if (!this.isSubProcess) {
|
|
372
416
|
this.broker.consume('api-q', onApiMessage, {
|
|
373
417
|
noAck: true,
|
|
@@ -387,8 +431,9 @@ ProcessExecution.prototype._activate = function activate() {
|
|
|
387
431
|
associations,
|
|
388
432
|
startActivities,
|
|
389
433
|
triggeredByEvent,
|
|
434
|
+
convergingGateways,
|
|
390
435
|
children
|
|
391
|
-
} = this[
|
|
436
|
+
} = this[K_ELEMENTS];
|
|
392
437
|
for (const flow of outboundMessageFlows) {
|
|
393
438
|
flow.activate();
|
|
394
439
|
flow.broker.subscribeTmp('event', '#', onMessageFlowEvent, {
|
|
@@ -413,6 +458,7 @@ ProcessExecution.prototype._activate = function activate() {
|
|
|
413
458
|
}
|
|
414
459
|
startActivities.clear();
|
|
415
460
|
triggeredByEvent.clear();
|
|
461
|
+
let startEventCount = 0;
|
|
416
462
|
for (const activity of children) {
|
|
417
463
|
if (activity.placeholder) continue;
|
|
418
464
|
activity.activate(this);
|
|
@@ -421,11 +467,18 @@ ProcessExecution.prototype._activate = function activate() {
|
|
|
421
467
|
consumerTag: '_process-activity-consumer',
|
|
422
468
|
priority: 200
|
|
423
469
|
});
|
|
424
|
-
if (activity.isStart)
|
|
425
|
-
|
|
470
|
+
if (activity.isStart) {
|
|
471
|
+
startActivities.add(activity);
|
|
472
|
+
if (activity.isStartEvent) startEventCount++;
|
|
473
|
+
}
|
|
474
|
+
if (activity.triggeredByEvent || activity.isCatching) triggeredByEvent.add(activity);
|
|
475
|
+
if (activity.isParallelGateway) convergingGateways.add(activity);
|
|
426
476
|
}
|
|
427
|
-
this[
|
|
477
|
+
this[K_ELEMENTS].startEventCount = startEventCount;
|
|
478
|
+
this[_constants.K_ACTIVATED] = true;
|
|
428
479
|
};
|
|
480
|
+
|
|
481
|
+
/** @internal */
|
|
429
482
|
ProcessExecution.prototype._deactivate = function deactivate() {
|
|
430
483
|
const broker = this.broker;
|
|
431
484
|
const executionId = this.executionId;
|
|
@@ -436,7 +489,7 @@ ProcessExecution.prototype._deactivate = function deactivate() {
|
|
|
436
489
|
flows,
|
|
437
490
|
associations,
|
|
438
491
|
outboundMessageFlows
|
|
439
|
-
} = this[
|
|
492
|
+
} = this[K_ELEMENTS];
|
|
440
493
|
for (const activity of children) {
|
|
441
494
|
if (activity.placeholder) continue;
|
|
442
495
|
activity.broker.cancel('_process-activity-consumer');
|
|
@@ -452,8 +505,105 @@ ProcessExecution.prototype._deactivate = function deactivate() {
|
|
|
452
505
|
flow.deactivate();
|
|
453
506
|
flow.broker.cancel('_process-message-consumer');
|
|
454
507
|
}
|
|
455
|
-
this[
|
|
508
|
+
this[_constants.K_ACTIVATED] = false;
|
|
456
509
|
};
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Discover converging parallel gateway peers for the peer monitor, reusing already discovered ones.
|
|
513
|
+
* @internal
|
|
514
|
+
*/
|
|
515
|
+
ProcessExecution.prototype._shakeOnStart = function shakeOnStart() {
|
|
516
|
+
const convergingGateways = this[K_ELEMENTS].convergingGateways;
|
|
517
|
+
if (!convergingGateways.size) return;
|
|
518
|
+
if (this._peersDiscovered()) {
|
|
519
|
+
this._debug(`reuse discovered parallel gateway peers (${convergingGateways.size})`);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
this._shakeElements();
|
|
523
|
+
this._debug(`forced shake to discover converging gateway peers (${convergingGateways.size})`);
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Whether every converging parallel gateway has discovered its peers in this runtime instance.
|
|
528
|
+
* Peers are a runtime cache and absent after recover, so a changed source is reshaken.
|
|
529
|
+
* @internal
|
|
530
|
+
*/
|
|
531
|
+
ProcessExecution.prototype._peersDiscovered = function peersDiscovered() {
|
|
532
|
+
const convergingGateways = this[K_ELEMENTS].convergingGateways;
|
|
533
|
+
for (const gateway of convergingGateways) {
|
|
534
|
+
if (!gateway[K_PEERS_DISCOVERED]) return false;
|
|
535
|
+
}
|
|
536
|
+
return true;
|
|
537
|
+
};
|
|
538
|
+
|
|
539
|
+
/** @internal */
|
|
540
|
+
ProcessExecution.prototype._shakeElements = function shakeElements(fromId) {
|
|
541
|
+
let executing = true;
|
|
542
|
+
const id = this.id;
|
|
543
|
+
if (!this.isRunning) {
|
|
544
|
+
executing = false;
|
|
545
|
+
this.executionId = (0, _shared.getUniqueId)(id);
|
|
546
|
+
this._activate();
|
|
547
|
+
}
|
|
548
|
+
const toShake = fromId ? [this.getActivityById(fromId)].filter(Boolean) : this[K_ELEMENTS].startActivities;
|
|
549
|
+
const result = {
|
|
550
|
+
sequences: new Map()
|
|
551
|
+
};
|
|
552
|
+
const convergingGateways = new Map();
|
|
553
|
+
const consumerTag = `_shaker-${this.executionId}`;
|
|
554
|
+
this.broker.subscribeTmp('event', '*.shake.*', (routingKey, {
|
|
555
|
+
content
|
|
556
|
+
}) => {
|
|
557
|
+
if (content.parent.id !== this.id) return;
|
|
558
|
+
switch (routingKey) {
|
|
559
|
+
case 'activity.shake.join':
|
|
560
|
+
{
|
|
561
|
+
const join = convergingGateways.get(content.join);
|
|
562
|
+
if (!join) {
|
|
563
|
+
convergingGateways.set(content.join, content);
|
|
564
|
+
} else {
|
|
565
|
+
join.sequence = join.sequence.concat(content.sequence);
|
|
566
|
+
}
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
case 'flow.shake.loop':
|
|
570
|
+
case 'activity.shake.linked':
|
|
571
|
+
case 'activity.shake.end':
|
|
572
|
+
{
|
|
573
|
+
const {
|
|
574
|
+
id: shakeId,
|
|
575
|
+
parent: shakeParent
|
|
576
|
+
} = content;
|
|
577
|
+
if (shakeParent.id !== id) return;
|
|
578
|
+
let seqnce;
|
|
579
|
+
if (!(seqnce = result.sequences.get(shakeId))) {
|
|
580
|
+
seqnce = [];
|
|
581
|
+
result.sequences.set(shakeId, seqnce);
|
|
582
|
+
}
|
|
583
|
+
seqnce.push({
|
|
584
|
+
...content,
|
|
585
|
+
isLooped: routingKey === 'flow.shake.loop'
|
|
586
|
+
});
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}, {
|
|
591
|
+
noAck: true,
|
|
592
|
+
consumerTag
|
|
593
|
+
});
|
|
594
|
+
for (const a of toShake) a.shake();
|
|
595
|
+
for (const [aid, c] of convergingGateways.entries()) {
|
|
596
|
+
this._debug(`manual shake of converging gateway <${aid}>`);
|
|
597
|
+
this.getActivityById(aid).broker.publish('api', 'activity.shake.continue', c, {
|
|
598
|
+
type: 'shake'
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
if (!executing) this._deactivate();
|
|
602
|
+
this.broker.cancel(consumerTag);
|
|
603
|
+
return result;
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
/** @internal */
|
|
457
607
|
ProcessExecution.prototype._onDelegateEvent = function onDelegateEvent(message) {
|
|
458
608
|
const eventType = message.properties.type;
|
|
459
609
|
let delegate = true;
|
|
@@ -463,8 +613,8 @@ ProcessExecution.prototype._onDelegateEvent = function onDelegateEvent(message)
|
|
|
463
613
|
} else {
|
|
464
614
|
this._debug(`delegate ${eventType} anonymous event`);
|
|
465
615
|
}
|
|
466
|
-
for (const activity of this[
|
|
467
|
-
if (activity.getStartActivities({
|
|
616
|
+
for (const activity of this[K_ELEMENTS].triggeredByEvent) {
|
|
617
|
+
if (activity.isSubProcess && activity.getStartActivities({
|
|
468
618
|
referenceId: content.message?.id,
|
|
469
619
|
referenceType: eventType
|
|
470
620
|
}).length) {
|
|
@@ -477,15 +627,23 @@ ProcessExecution.prototype._onDelegateEvent = function onDelegateEvent(message)
|
|
|
477
627
|
});
|
|
478
628
|
return delegate;
|
|
479
629
|
};
|
|
630
|
+
|
|
631
|
+
/** @internal */
|
|
480
632
|
ProcessExecution.prototype._onMessageFlowEvent = function onMessageFlowEvent(routingKey, message) {
|
|
481
633
|
this.broker.publish('message', routingKey, (0, _messageHelper.cloneContent)(message.content), message.properties);
|
|
482
634
|
};
|
|
635
|
+
|
|
636
|
+
/** @internal */
|
|
483
637
|
ProcessExecution.prototype._onActivityEvent = function onActivityEvent(routingKey, message) {
|
|
484
|
-
|
|
485
|
-
|
|
638
|
+
const {
|
|
639
|
+
fields,
|
|
640
|
+
content,
|
|
641
|
+
properties
|
|
642
|
+
} = message;
|
|
643
|
+
if (fields.redelivered && properties.persistent === false) return;
|
|
486
644
|
const parent = content.parent = content.parent || {};
|
|
487
|
-
let delegate =
|
|
488
|
-
const shaking =
|
|
645
|
+
let delegate = properties.delegate;
|
|
646
|
+
const shaking = properties.type === 'shake';
|
|
489
647
|
const isDirectChild = content.parent.id === this.id;
|
|
490
648
|
if (isDirectChild) {
|
|
491
649
|
parent.executionId = this.executionId;
|
|
@@ -497,17 +655,17 @@ ProcessExecution.prototype._onActivityEvent = function onActivityEvent(routingKe
|
|
|
497
655
|
});
|
|
498
656
|
}
|
|
499
657
|
if (delegate) delegate = this._onDelegateEvent(message);
|
|
500
|
-
this[
|
|
658
|
+
this[K_TRACKER].track(routingKey, message);
|
|
501
659
|
this.broker.publish('event', routingKey, content, {
|
|
502
|
-
...
|
|
660
|
+
...properties,
|
|
503
661
|
delegate,
|
|
504
662
|
mandatory: false
|
|
505
663
|
});
|
|
506
|
-
if (shaking) return
|
|
664
|
+
if (shaking) return;
|
|
507
665
|
if (!isDirectChild) return;
|
|
508
666
|
switch (routingKey) {
|
|
509
667
|
case 'process.terminate':
|
|
510
|
-
return this[
|
|
668
|
+
return this[K_ACTIVITY_Q].queueMessage({
|
|
511
669
|
routingKey: 'execution.terminate'
|
|
512
670
|
}, (0, _messageHelper.cloneContent)(content), {
|
|
513
671
|
type: 'terminate',
|
|
@@ -516,11 +674,13 @@ ProcessExecution.prototype._onActivityEvent = function onActivityEvent(routingKe
|
|
|
516
674
|
case 'activity.stop':
|
|
517
675
|
return;
|
|
518
676
|
}
|
|
519
|
-
this[
|
|
677
|
+
this[K_ACTIVITY_Q].queueMessage(message.fields, (0, _messageHelper.cloneContent)(content), {
|
|
520
678
|
persistent: true,
|
|
521
679
|
...message.properties
|
|
522
680
|
});
|
|
523
681
|
};
|
|
682
|
+
|
|
683
|
+
/** @internal */
|
|
524
684
|
ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey, message) {
|
|
525
685
|
if (message.fields.redelivered && message.properties.persistent === false) return message.ack();
|
|
526
686
|
const content = message.content;
|
|
@@ -537,7 +697,7 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
|
|
|
537
697
|
case 'execution.discard.detached':
|
|
538
698
|
{
|
|
539
699
|
message.ack();
|
|
540
|
-
for (const detached of this[
|
|
700
|
+
for (const detached of this[K_ELEMENTS].detachedActivities) {
|
|
541
701
|
this._getChildApi(detached).discard();
|
|
542
702
|
}
|
|
543
703
|
return;
|
|
@@ -548,7 +708,7 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
|
|
|
548
708
|
case 'activity.error.caught':
|
|
549
709
|
{
|
|
550
710
|
let prevMsg;
|
|
551
|
-
for (const msg of this[
|
|
711
|
+
for (const msg of this[K_ELEMENTS].postponed) {
|
|
552
712
|
if (msg.content.executionId === content.executionId) {
|
|
553
713
|
prevMsg = msg;
|
|
554
714
|
break;
|
|
@@ -557,7 +717,6 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
|
|
|
557
717
|
if (!prevMsg) return message.ack();
|
|
558
718
|
break;
|
|
559
719
|
}
|
|
560
|
-
case 'flow.looped':
|
|
561
720
|
case 'activity.leave':
|
|
562
721
|
return this._onChildCompleted(message);
|
|
563
722
|
}
|
|
@@ -565,7 +724,7 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
|
|
|
565
724
|
switch (routingKey) {
|
|
566
725
|
case 'activity.detach':
|
|
567
726
|
{
|
|
568
|
-
this[
|
|
727
|
+
this[K_ELEMENTS].detachedActivities.add((0, _messageHelper.cloneMessage)(message));
|
|
569
728
|
break;
|
|
570
729
|
}
|
|
571
730
|
case 'activity.cancel':
|
|
@@ -584,17 +743,24 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
|
|
|
584
743
|
}
|
|
585
744
|
break;
|
|
586
745
|
}
|
|
746
|
+
case 'activity.end':
|
|
747
|
+
{
|
|
748
|
+
if (!(content.isStartEvent || this.getActivityById(content.id)?.isStartEvent)) break;
|
|
749
|
+
if (this[K_ELEMENTS].startEventCount <= 1) break;
|
|
750
|
+
this._discardArmedStartEvents(content.id);
|
|
751
|
+
break;
|
|
752
|
+
}
|
|
587
753
|
case 'activity.error':
|
|
588
754
|
{
|
|
589
755
|
let eventCaughtBy;
|
|
590
|
-
for (const msg of this[
|
|
756
|
+
for (const msg of this[K_ELEMENTS].postponed) {
|
|
591
757
|
if (msg.fields.routingKey === 'activity.catch' && msg.content.source?.executionId === content.executionId) {
|
|
592
758
|
eventCaughtBy = msg;
|
|
593
759
|
break;
|
|
594
760
|
}
|
|
595
761
|
}
|
|
596
762
|
if (eventCaughtBy) {
|
|
597
|
-
this[
|
|
763
|
+
this[K_ACTIVITY_Q].queueMessage({
|
|
598
764
|
routingKey: 'activity.error.caught'
|
|
599
765
|
}, (0, _messageHelper.cloneContent)(content), {
|
|
600
766
|
persistent: true,
|
|
@@ -608,16 +774,20 @@ ProcessExecution.prototype._onChildMessage = function onChildMessage(routingKey,
|
|
|
608
774
|
}
|
|
609
775
|
}
|
|
610
776
|
};
|
|
777
|
+
|
|
778
|
+
/** @internal */
|
|
611
779
|
ProcessExecution.prototype._stateChangeMessage = function stateChangeMessage(message, postponeMessage) {
|
|
612
780
|
const previousMsg = this._popPostponed(message.content);
|
|
613
781
|
if (previousMsg) previousMsg.ack();
|
|
614
|
-
if (postponeMessage) this[
|
|
782
|
+
if (postponeMessage) this[K_ELEMENTS].postponed.add(message);
|
|
615
783
|
};
|
|
784
|
+
|
|
785
|
+
/** @internal */
|
|
616
786
|
ProcessExecution.prototype._popPostponed = function popPostponed(byContent) {
|
|
617
787
|
const {
|
|
618
788
|
postponed,
|
|
619
789
|
detachedActivities
|
|
620
|
-
} = this[
|
|
790
|
+
} = this[K_ELEMENTS];
|
|
621
791
|
let postponedMsg;
|
|
622
792
|
if (byContent.sequenceId) {
|
|
623
793
|
for (const msg of postponed) {
|
|
@@ -644,19 +814,25 @@ ProcessExecution.prototype._popPostponed = function popPostponed(byContent) {
|
|
|
644
814
|
}
|
|
645
815
|
return postponedMsg;
|
|
646
816
|
};
|
|
817
|
+
|
|
818
|
+
/** @internal */
|
|
647
819
|
ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message) {
|
|
648
820
|
this._stateChangeMessage(message, false);
|
|
649
821
|
if (message.fields.redelivered) return message.ack();
|
|
650
822
|
const {
|
|
651
823
|
id,
|
|
652
824
|
type,
|
|
653
|
-
|
|
825
|
+
isParallelGateway
|
|
654
826
|
} = message.content;
|
|
827
|
+
if (isParallelGateway) {
|
|
828
|
+
for (const inb of message.content.inbound) {
|
|
829
|
+
this._popPostponed(inb)?.ack();
|
|
830
|
+
}
|
|
831
|
+
}
|
|
655
832
|
const {
|
|
656
833
|
postponed,
|
|
657
|
-
detachedActivities
|
|
658
|
-
|
|
659
|
-
} = this[kElements];
|
|
834
|
+
detachedActivities
|
|
835
|
+
} = this[K_ELEMENTS];
|
|
660
836
|
const postponedCount = postponed.size;
|
|
661
837
|
if (!postponedCount) {
|
|
662
838
|
this._debug(`left <${id}> (${type}), pending runs ${postponedCount}`);
|
|
@@ -664,9 +840,9 @@ ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message
|
|
|
664
840
|
return this._complete('completed');
|
|
665
841
|
}
|
|
666
842
|
message.ack();
|
|
667
|
-
this._debug(`left <${id}> (${type}), pending activities ${postponedCount}`);
|
|
843
|
+
this._debug(`left <${id}> (${type}), pending activities ${postponedCount} ${[...postponed].map(m => m.content.id)}`);
|
|
668
844
|
if (postponedCount && postponedCount === detachedActivities.size) {
|
|
669
|
-
return this[
|
|
845
|
+
return this[K_ACTIVITY_Q].queueMessage({
|
|
670
846
|
routingKey: 'execution.discard.detached'
|
|
671
847
|
}, {
|
|
672
848
|
id: this.id,
|
|
@@ -676,21 +852,9 @@ ProcessExecution.prototype._onChildCompleted = function onChildCompleted(message
|
|
|
676
852
|
type: 'cancel'
|
|
677
853
|
});
|
|
678
854
|
}
|
|
679
|
-
if (isEnd && startActivities.size) {
|
|
680
|
-
const startSequences = this[kElements].startSequences;
|
|
681
|
-
for (const msg of postponed) {
|
|
682
|
-
const postponedId = msg.content.id;
|
|
683
|
-
const startSequence = startSequences[postponedId];
|
|
684
|
-
if (startSequence) {
|
|
685
|
-
if (startSequence.content.sequence.some(({
|
|
686
|
-
id: sid
|
|
687
|
-
}) => sid === id)) {
|
|
688
|
-
this._getChildApi(msg).discard();
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
855
|
};
|
|
856
|
+
|
|
857
|
+
/** @internal */
|
|
694
858
|
ProcessExecution.prototype._stopExecution = function stopExecution(message) {
|
|
695
859
|
const postponedCount = this.postponedCount;
|
|
696
860
|
this._debug(`stop process execution (stop child executions ${postponedCount})`);
|
|
@@ -698,18 +862,20 @@ ProcessExecution.prototype._stopExecution = function stopExecution(message) {
|
|
|
698
862
|
for (const api of this.getPostponed()) api.stop();
|
|
699
863
|
}
|
|
700
864
|
this._deactivate();
|
|
701
|
-
this[
|
|
865
|
+
this[_constants.K_STOPPED] = true;
|
|
702
866
|
return this.broker.publish(this._exchangeName, `execution.stopped.${this.executionId}`, {
|
|
703
|
-
...this[
|
|
867
|
+
...this[_constants.K_EXECUTE_MESSAGE].content,
|
|
704
868
|
...(message && message.content)
|
|
705
869
|
}, {
|
|
706
870
|
type: 'stopped',
|
|
707
871
|
persistent: false
|
|
708
872
|
});
|
|
709
873
|
};
|
|
874
|
+
|
|
875
|
+
/** @internal */
|
|
710
876
|
ProcessExecution.prototype._onDiscard = function onDiscard() {
|
|
711
877
|
this._deactivate();
|
|
712
|
-
const postponed = this[
|
|
878
|
+
const postponed = this[K_ELEMENTS].postponed;
|
|
713
879
|
const running = new Set(postponed);
|
|
714
880
|
postponed.clear();
|
|
715
881
|
this._debug(`discard process execution (discard child executions ${running.size})`);
|
|
@@ -720,17 +886,19 @@ ProcessExecution.prototype._onDiscard = function onDiscard() {
|
|
|
720
886
|
for (const flow of this.getAssociations()) flow.stop();
|
|
721
887
|
for (const msg of running) this._getChildApi(msg).discard();
|
|
722
888
|
}
|
|
723
|
-
this[
|
|
889
|
+
this[K_ACTIVITY_Q].purge();
|
|
724
890
|
return this._complete('discard');
|
|
725
891
|
};
|
|
892
|
+
|
|
893
|
+
/** @internal */
|
|
726
894
|
ProcessExecution.prototype._onCancel = function onCancel() {
|
|
727
|
-
const postponed = this[
|
|
895
|
+
const postponed = this[K_ELEMENTS].postponed;
|
|
728
896
|
const running = new Set(postponed);
|
|
729
897
|
const isTransaction = this.isTransaction;
|
|
730
898
|
if (isTransaction) {
|
|
731
899
|
this._debug(`cancel transaction execution (cancel child executions ${running.size})`);
|
|
732
|
-
this[
|
|
733
|
-
this.broker.publish('event', 'transaction.cancel', (0, _messageHelper.cloneMessage)(this[
|
|
900
|
+
this[_constants.K_STATUS] = 'cancel';
|
|
901
|
+
this.broker.publish('event', 'transaction.cancel', (0, _messageHelper.cloneMessage)(this[_constants.K_EXECUTE_MESSAGE], {
|
|
734
902
|
state: 'cancel'
|
|
735
903
|
}));
|
|
736
904
|
for (const msg of running) {
|
|
@@ -747,6 +915,8 @@ ProcessExecution.prototype._onCancel = function onCancel() {
|
|
|
747
915
|
}
|
|
748
916
|
}
|
|
749
917
|
};
|
|
918
|
+
|
|
919
|
+
/** @internal */
|
|
750
920
|
ProcessExecution.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
751
921
|
if (message.properties.delegate) {
|
|
752
922
|
return this._delegateApiMessage(routingKey, message);
|
|
@@ -763,7 +933,7 @@ ProcessExecution.prototype._onApiMessage = function onApiMessage(routingKey, mes
|
|
|
763
933
|
case 'discard':
|
|
764
934
|
return this.discard(message);
|
|
765
935
|
case 'stop':
|
|
766
|
-
this[
|
|
936
|
+
this[K_ACTIVITY_Q].queueMessage({
|
|
767
937
|
routingKey: 'execution.stop'
|
|
768
938
|
}, (0, _messageHelper.cloneContent)(message.content), {
|
|
769
939
|
persistent: false
|
|
@@ -771,6 +941,8 @@ ProcessExecution.prototype._onApiMessage = function onApiMessage(routingKey, mes
|
|
|
771
941
|
break;
|
|
772
942
|
}
|
|
773
943
|
};
|
|
944
|
+
|
|
945
|
+
/** @internal */
|
|
774
946
|
ProcessExecution.prototype._delegateApiMessage = function delegateApiMessage(routingKey, message, continueOnConsumed) {
|
|
775
947
|
const correlationId = message.properties.correlationId || (0, _shared.getUniqueId)(this.executionId);
|
|
776
948
|
this._debug(`delegate api ${routingKey} message to children, with correlationId <${correlationId}>`);
|
|
@@ -785,16 +957,18 @@ ProcessExecution.prototype._delegateApiMessage = function delegateApiMessage(rou
|
|
|
785
957
|
consumerTag: `_ct-delegate-${correlationId}`,
|
|
786
958
|
noAck: true
|
|
787
959
|
});
|
|
788
|
-
for (const child of this[
|
|
960
|
+
for (const child of this[K_ELEMENTS].children) {
|
|
789
961
|
if (child.placeholder) continue;
|
|
790
962
|
child.broker.publish('api', routingKey, (0, _messageHelper.cloneContent)(message.content), message.properties);
|
|
791
963
|
if (consumed && !continueOnConsumed) break;
|
|
792
964
|
}
|
|
793
965
|
return broker.cancel(`_ct-delegate-${correlationId}`);
|
|
794
966
|
};
|
|
967
|
+
|
|
968
|
+
/** @internal */
|
|
795
969
|
ProcessExecution.prototype._complete = function complete(completionType, content) {
|
|
796
970
|
this._deactivate();
|
|
797
|
-
this[
|
|
971
|
+
this[_constants.K_COMPLETED] = true;
|
|
798
972
|
const status = this.status;
|
|
799
973
|
switch (this.status) {
|
|
800
974
|
case 'cancel':
|
|
@@ -806,11 +980,11 @@ ProcessExecution.prototype._complete = function complete(completionType, content
|
|
|
806
980
|
break;
|
|
807
981
|
default:
|
|
808
982
|
this._debug(`process execution ${completionType}`);
|
|
809
|
-
this[
|
|
983
|
+
this[_constants.K_STATUS] = completionType;
|
|
810
984
|
}
|
|
811
985
|
const broker = this.broker;
|
|
812
|
-
this[
|
|
813
|
-
|
|
986
|
+
this[K_ACTIVITY_Q].delete();
|
|
987
|
+
broker.publish(this._exchangeName, `execution.${completionType}.${this.executionId}`, (0, _messageHelper.cloneContent)(this[_constants.K_EXECUTE_MESSAGE].content, {
|
|
814
988
|
output: {
|
|
815
989
|
...this.environment.output
|
|
816
990
|
},
|
|
@@ -821,10 +995,12 @@ ProcessExecution.prototype._complete = function complete(completionType, content
|
|
|
821
995
|
mandatory: completionType === 'error'
|
|
822
996
|
});
|
|
823
997
|
};
|
|
998
|
+
|
|
999
|
+
/** @internal */
|
|
824
1000
|
ProcessExecution.prototype._terminate = function terminate(message) {
|
|
825
|
-
this[
|
|
1001
|
+
this[_constants.K_STATUS] = 'terminated';
|
|
826
1002
|
this._debug('terminating process execution');
|
|
827
|
-
const postponed = this[
|
|
1003
|
+
const postponed = this[K_ELEMENTS].postponed;
|
|
828
1004
|
const running = new Set(postponed);
|
|
829
1005
|
postponed.clear();
|
|
830
1006
|
for (const flow of this.getSequenceFlows()) flow.stop();
|
|
@@ -840,20 +1016,66 @@ ProcessExecution.prototype._terminate = function terminate(message) {
|
|
|
840
1016
|
this._getChildApi(msg).stop();
|
|
841
1017
|
msg.ack();
|
|
842
1018
|
}
|
|
843
|
-
this[
|
|
1019
|
+
this[K_ACTIVITY_Q].purge();
|
|
844
1020
|
};
|
|
1021
|
+
|
|
1022
|
+
/** @internal */
|
|
845
1023
|
ProcessExecution.prototype._getFlowById = function getFlowById(flowId) {
|
|
846
|
-
return this[
|
|
1024
|
+
return this[K_ELEMENTS].flows.find(f => f.id === flowId);
|
|
847
1025
|
};
|
|
1026
|
+
|
|
1027
|
+
/** @internal */
|
|
848
1028
|
ProcessExecution.prototype._getAssociationById = function getAssociationById(associationId) {
|
|
849
|
-
return this[
|
|
1029
|
+
return this[K_ELEMENTS].associations.find(a => a.id === associationId);
|
|
850
1030
|
};
|
|
1031
|
+
|
|
1032
|
+
/** @internal */
|
|
851
1033
|
ProcessExecution.prototype._getMessageFlowById = function getMessageFlowById(flowId) {
|
|
852
|
-
return this[
|
|
1034
|
+
return this[K_ELEMENTS].outboundMessageFlows.find(f => f.id === flowId);
|
|
853
1035
|
};
|
|
1036
|
+
|
|
1037
|
+
/** @internal */
|
|
854
1038
|
ProcessExecution.prototype._getChildById = function getChildById(childId) {
|
|
855
1039
|
return this.getActivityById(childId) || this._getFlowById(childId);
|
|
856
1040
|
};
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Discard the other armed start events once one mutually exclusive entry point wins.
|
|
1044
|
+
* Resolves the start-event flag from the live activity so recovered pre-flag state is handled.
|
|
1045
|
+
* @internal
|
|
1046
|
+
*/
|
|
1047
|
+
ProcessExecution.prototype._discardArmedStartEvents = function discardArmedStartEvents(winnerId) {
|
|
1048
|
+
const elements = this[K_ELEMENTS];
|
|
1049
|
+
const startPeers = [];
|
|
1050
|
+
for (const msg of elements.postponed) {
|
|
1051
|
+
const peerId = msg.content.id;
|
|
1052
|
+
if (peerId === winnerId) continue;
|
|
1053
|
+
if (this.getActivityById(peerId)?.isStartEvent) startPeers.push(msg);
|
|
1054
|
+
}
|
|
1055
|
+
if (!startPeers.length) return;
|
|
1056
|
+
elements.startEventCount = 0;
|
|
1057
|
+
for (const msg of startPeers) this._getChildApi(msg).discard();
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* On resume of a state from an older major, discard start events left armed when another entry
|
|
1062
|
+
* point already won before recovery. The winning start event's `activity.end` cannot replay, so
|
|
1063
|
+
* the live discard trigger never fires.
|
|
1064
|
+
* @internal
|
|
1065
|
+
*/
|
|
1066
|
+
ProcessExecution.prototype._reconcileStartEvents = function reconcileStartEvents() {
|
|
1067
|
+
const elements = this[K_ELEMENTS];
|
|
1068
|
+
if (elements.startEventCount <= 1) return;
|
|
1069
|
+
if (!(this[K_RECOVERED_VERSION] < _constants.STATE_VERSION)) return;
|
|
1070
|
+
for (const child of elements.children) {
|
|
1071
|
+
if (child.isStartEvent && child.counters.taken) {
|
|
1072
|
+
this._discardArmedStartEvents();
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
|
|
1078
|
+
/** @internal */
|
|
857
1079
|
ProcessExecution.prototype._getChildApi = function getChildApi(message) {
|
|
858
1080
|
const content = message.content;
|
|
859
1081
|
let child = this._getChildById(content.id);
|
|
@@ -867,11 +1089,8 @@ ProcessExecution.prototype._getChildApi = function getChildApi(message) {
|
|
|
867
1089
|
if (child) return child.getApi(message);
|
|
868
1090
|
}
|
|
869
1091
|
};
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
if (routingKey !== 'activity.shake.end') return;
|
|
873
|
-
this[kElements].startSequences[message.content.id] = (0, _messageHelper.cloneMessage)(message);
|
|
874
|
-
};
|
|
1092
|
+
|
|
1093
|
+
/** @internal */
|
|
875
1094
|
ProcessExecution.prototype._debug = function debugMessage(logMessage) {
|
|
876
|
-
this[
|
|
1095
|
+
this[K_PARENT].logger.debug(`<${this.executionId} (${this.id})> ${logMessage}`);
|
|
877
1096
|
};
|