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
|
@@ -2,696 +2,746 @@ import {ProcessApi} from '../Api';
|
|
|
2
2
|
import {cloneContent, cloneMessage, pushParent} from '../messageHelper';
|
|
3
3
|
import {getUniqueId} from '../shared';
|
|
4
4
|
|
|
5
|
-
export default
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
get status() {
|
|
39
|
-
return status;
|
|
40
|
-
},
|
|
41
|
-
get stopped() {
|
|
42
|
-
return stopped;
|
|
43
|
-
},
|
|
44
|
-
get postponedCount() {
|
|
45
|
-
return postponed.length;
|
|
46
|
-
},
|
|
47
|
-
get isRunning() {
|
|
48
|
-
if (activated) return true;
|
|
49
|
-
return false;
|
|
50
|
-
},
|
|
51
|
-
discard,
|
|
52
|
-
execute,
|
|
53
|
-
getApi,
|
|
54
|
-
getActivityById,
|
|
55
|
-
getActivities,
|
|
56
|
-
getPostponed,
|
|
57
|
-
getSequenceFlows,
|
|
58
|
-
getState,
|
|
59
|
-
recover,
|
|
60
|
-
shake,
|
|
61
|
-
stop,
|
|
5
|
+
export default ProcessExecution;
|
|
6
|
+
|
|
7
|
+
const kActivated = Symbol.for('activated');
|
|
8
|
+
const kActivityQ = Symbol.for('activityQ');
|
|
9
|
+
const kCompleted = Symbol.for('completed');
|
|
10
|
+
const kElements = Symbol.for('elements');
|
|
11
|
+
const kExecuteMessage = Symbol.for('executeMessage');
|
|
12
|
+
const kMessageHandlers = Symbol.for('messageHandlers');
|
|
13
|
+
const kParent = Symbol.for('parent');
|
|
14
|
+
const kStatus = Symbol.for('status');
|
|
15
|
+
const kStopped = Symbol.for('stopped');
|
|
16
|
+
|
|
17
|
+
function ProcessExecution(parentActivity, context) {
|
|
18
|
+
const {id, type, broker, isSubProcess} = parentActivity;
|
|
19
|
+
|
|
20
|
+
this[kParent] = parentActivity;
|
|
21
|
+
this.id = id;
|
|
22
|
+
this.type = type;
|
|
23
|
+
this.isSubProcess = isSubProcess;
|
|
24
|
+
this.broker = broker;
|
|
25
|
+
this.environment = context.environment;
|
|
26
|
+
this.context = context;
|
|
27
|
+
|
|
28
|
+
this[kElements] = {
|
|
29
|
+
children: context.getActivities(id),
|
|
30
|
+
associations: context.getAssociations(id),
|
|
31
|
+
flows: context.getSequenceFlows(id),
|
|
32
|
+
outboundMessageFlows: context.getMessageFlows(id),
|
|
33
|
+
startActivities: [],
|
|
34
|
+
triggeredByEvent: [],
|
|
35
|
+
detachedActivities: [],
|
|
36
|
+
startSequences: {},
|
|
37
|
+
postponed: [],
|
|
62
38
|
};
|
|
63
39
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
function execute(executeMessage) {
|
|
67
|
-
if (!executeMessage) throw new Error('Process execution requires message');
|
|
68
|
-
if (!executeMessage.content || !executeMessage.content.executionId) throw new Error('Process execution requires execution id');
|
|
69
|
-
|
|
70
|
-
const isRedelivered = executeMessage.fields.redelivered;
|
|
71
|
-
executionId = executeMessage.content.executionId;
|
|
72
|
-
prepare();
|
|
73
|
-
|
|
74
|
-
stateMessage = cloneMessage(executeMessage);
|
|
75
|
-
stateMessage.content = {...stateMessage.content, executionId, state: 'start'};
|
|
76
|
-
|
|
77
|
-
stopped = false;
|
|
78
|
-
|
|
79
|
-
environment.assignVariables(executeMessage);
|
|
80
|
-
activityQ = broker.assertQueue(`execute-${executionId}-q`, {durable: true, autoDelete: false});
|
|
40
|
+
const exchangeName = this._exchangeName = isSubProcess ? 'subprocess-execution' : 'execution';
|
|
41
|
+
broker.assertExchange(exchangeName, 'topic', {autoDelete: false, durable: true});
|
|
81
42
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
43
|
+
this[kCompleted] = false;
|
|
44
|
+
this[kStopped] = false;
|
|
45
|
+
this[kActivated] = false;
|
|
46
|
+
this[kStatus] = 'init';
|
|
47
|
+
this.executionId = undefined;
|
|
48
|
+
|
|
49
|
+
this[kMessageHandlers] = {
|
|
50
|
+
onActivityEvent: this._onActivityEvent.bind(this),
|
|
51
|
+
onApiMessage: this._onApiMessage.bind(this),
|
|
52
|
+
onChildMessage: this._onChildMessage.bind(this),
|
|
53
|
+
onMessageFlowEvent: this._onMessageFlowEvent.bind(this),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
85
56
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
57
|
+
const proto = ProcessExecution.prototype;
|
|
58
|
+
|
|
59
|
+
Object.defineProperty(proto, 'stopped', {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
get() {
|
|
62
|
+
return this[kStopped];
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
Object.defineProperty(proto, 'completed', {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get() {
|
|
69
|
+
return this[kCompleted];
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
Object.defineProperty(proto, 'status', {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
get() {
|
|
76
|
+
return this[kStatus];
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
Object.defineProperty(proto, 'postponedCount', {
|
|
81
|
+
get() {
|
|
82
|
+
return this[kElements].postponed.length;
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
Object.defineProperty(proto, 'isRunning', {
|
|
87
|
+
get() {
|
|
88
|
+
return this[kActivated];
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
proto.execute = function execute(executeMessage) {
|
|
93
|
+
if (!executeMessage) throw new Error('Process execution requires message');
|
|
94
|
+
if (!executeMessage.content || !executeMessage.content.executionId) throw new Error('Process execution requires execution id');
|
|
95
|
+
|
|
96
|
+
const executionId = this.executionId = executeMessage.content.executionId;
|
|
97
|
+
|
|
98
|
+
this[kExecuteMessage] = cloneMessage(executeMessage, {
|
|
99
|
+
executionId,
|
|
100
|
+
state: 'start',
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
this[kStopped] = false;
|
|
104
|
+
|
|
105
|
+
this.environment.assignVariables(executeMessage);
|
|
106
|
+
this[kActivityQ] = this.broker.assertQueue(`execute-${executionId}-q`, {durable: true, autoDelete: false});
|
|
107
|
+
|
|
108
|
+
if (executeMessage.fields.redelivered) {
|
|
109
|
+
return this.resume();
|
|
90
110
|
}
|
|
91
111
|
|
|
92
|
-
|
|
93
|
-
|
|
112
|
+
this._debug(`execute ${this.isSubProcess ? 'sub process' : 'process'}`);
|
|
113
|
+
this._activate();
|
|
114
|
+
this._start();
|
|
115
|
+
return true;
|
|
116
|
+
};
|
|
94
117
|
|
|
95
|
-
|
|
118
|
+
proto.resume = function resume() {
|
|
119
|
+
this._debug(`resume process execution at ${this.status}`);
|
|
96
120
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (startActivities.length > 1) {
|
|
100
|
-
startActivities.forEach((a) => a.shake());
|
|
101
|
-
}
|
|
121
|
+
if (this[kCompleted]) return this._complete('completed');
|
|
102
122
|
|
|
103
|
-
|
|
104
|
-
detachedActivities.splice(0);
|
|
105
|
-
activityQ.consume(onChildMessage, {prefetch: 1000, consumerTag: `_process-activity-${executionId}`});
|
|
123
|
+
this._activate();
|
|
106
124
|
|
|
107
|
-
|
|
108
|
-
switch (status) {
|
|
109
|
-
case 'init':
|
|
110
|
-
return start();
|
|
111
|
-
case 'executing': {
|
|
112
|
-
if (!postponed.length) return complete('completed');
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
125
|
+
const {startActivities, detachedActivities, postponed} = this[kElements];
|
|
116
126
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (!activity) return;
|
|
120
|
-
if (content.placeholder) return;
|
|
121
|
-
activity.resume();
|
|
122
|
-
});
|
|
127
|
+
if (startActivities.length > 1) {
|
|
128
|
+
for (const a of startActivities) a.shake();
|
|
123
129
|
}
|
|
124
130
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return complete('completed');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
status = 'start';
|
|
131
|
+
postponed.splice(0);
|
|
132
|
+
detachedActivities.splice(0);
|
|
131
133
|
|
|
132
|
-
|
|
134
|
+
this[kActivityQ].consume(this[kMessageHandlers].onChildMessage, {
|
|
135
|
+
prefetch: 1000,
|
|
136
|
+
consumerTag: `_process-activity-${this.executionId}`,
|
|
137
|
+
});
|
|
133
138
|
|
|
134
|
-
|
|
139
|
+
if (this[kCompleted]) return;
|
|
135
140
|
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
switch (this.status) {
|
|
142
|
+
case 'init':
|
|
143
|
+
return this._start();
|
|
144
|
+
case 'executing': {
|
|
145
|
+
if (!postponed.length) return this._complete('completed');
|
|
146
|
+
break;
|
|
138
147
|
}
|
|
148
|
+
}
|
|
139
149
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
activityQ.assertConsumer(onChildMessage, {prefetch: 1000, consumerTag: `_process-activity-${executionId}`});
|
|
150
|
+
for (const {content} of postponed.slice()) {
|
|
151
|
+
const activity = this.getActivityById(content.id);
|
|
152
|
+
if (!activity) continue;
|
|
153
|
+
if (content.placeholder) continue;
|
|
154
|
+
activity.resume();
|
|
146
155
|
}
|
|
156
|
+
};
|
|
147
157
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
prepare();
|
|
158
|
+
proto.recover = function recover(state) {
|
|
159
|
+
if (!state) return this;
|
|
160
|
+
this.executionId = state.executionId;
|
|
152
161
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
162
|
+
this[kStopped] = state.stopped;
|
|
163
|
+
this[kCompleted] = state.completed;
|
|
164
|
+
this[kStatus] = state.status;
|
|
156
165
|
|
|
157
|
-
|
|
166
|
+
this._debug(`recover process execution at ${this.status}`);
|
|
158
167
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
});
|
|
168
|
+
if (state.messageFlows) {
|
|
169
|
+
for (const flowState of state.messageFlows) {
|
|
170
|
+
const flow = this._getMessageFlowById(flowState.id);
|
|
171
|
+
if (!flow) continue;
|
|
172
|
+
flow.recover(flowState);
|
|
165
173
|
}
|
|
174
|
+
}
|
|
166
175
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
});
|
|
176
|
+
if (state.associations) {
|
|
177
|
+
for (const associationState of state.associations) {
|
|
178
|
+
const association = this._getAssociationById(associationState.id);
|
|
179
|
+
if (!association) continue;
|
|
180
|
+
association.recover(associationState);
|
|
173
181
|
}
|
|
182
|
+
}
|
|
174
183
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
});
|
|
184
|
+
if (state.flows) {
|
|
185
|
+
for (const flowState of state.flows) {
|
|
186
|
+
const flow = this._getFlowById(flowState.id);
|
|
187
|
+
if (!flow) continue;
|
|
188
|
+
flow.recover(flowState);
|
|
181
189
|
}
|
|
190
|
+
}
|
|
182
191
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
192
|
+
if (state.children) {
|
|
193
|
+
for (const childState of state.children) {
|
|
194
|
+
const child = this.getActivityById(childState.id);
|
|
195
|
+
if (!child) continue;
|
|
187
196
|
|
|
188
|
-
|
|
189
|
-
});
|
|
197
|
+
child.recover(childState);
|
|
190
198
|
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return this;
|
|
202
|
+
};
|
|
191
203
|
|
|
192
|
-
|
|
204
|
+
proto.shake = function shake(fromId) {
|
|
205
|
+
let executing = true;
|
|
206
|
+
const id = this.id;
|
|
207
|
+
if (!this.isRunning) {
|
|
208
|
+
executing = false;
|
|
209
|
+
this.executionId = getUniqueId(id);
|
|
210
|
+
this._activate();
|
|
193
211
|
}
|
|
212
|
+
const toShake = fromId ? [this.getActivityById(fromId)].filter(Boolean) : this[kElements].startActivities;
|
|
194
213
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
switch (routingKey) {
|
|
209
|
-
case 'flow.shake.loop':
|
|
210
|
-
isLooped = true;
|
|
211
|
-
case 'activity.shake.end':
|
|
212
|
-
onShakeEnd(content, isLooped);
|
|
213
|
-
break;
|
|
214
|
+
const result = {};
|
|
215
|
+
this.broker.subscribeTmp('event', '*.shake.*', (routingKey, {content}) => {
|
|
216
|
+
let isLooped = false;
|
|
217
|
+
switch (routingKey) {
|
|
218
|
+
case 'flow.shake.loop':
|
|
219
|
+
isLooped = true;
|
|
220
|
+
case 'activity.shake.end': {
|
|
221
|
+
const {id: shakeId, parent: shakeParent} = content;
|
|
222
|
+
if (shakeParent.id !== id) return;
|
|
223
|
+
|
|
224
|
+
result[shakeId] = result[shakeId] || [];
|
|
225
|
+
result[shakeId].push({...content, isLooped});
|
|
226
|
+
break;
|
|
214
227
|
}
|
|
215
|
-
}
|
|
228
|
+
}
|
|
229
|
+
}, {noAck: true, consumerTag: `_shaker-${this.executionId}`});
|
|
216
230
|
|
|
217
|
-
|
|
231
|
+
for (const a of toShake) a.shake();
|
|
218
232
|
|
|
219
|
-
|
|
220
|
-
|
|
233
|
+
if (!executing) this._deactivate();
|
|
234
|
+
this.broker.cancel(`_shaker-${this.executionId}`);
|
|
221
235
|
|
|
222
|
-
|
|
236
|
+
return result;
|
|
237
|
+
};
|
|
223
238
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
239
|
+
proto.stop = function stop() {
|
|
240
|
+
this.getApi().stop();
|
|
241
|
+
};
|
|
227
242
|
|
|
228
|
-
|
|
229
|
-
|
|
243
|
+
proto.getPostponed = function getPostponed(filterFn) {
|
|
244
|
+
return this[kElements].postponed.slice().reduce((result, msg) => {
|
|
245
|
+
const api = this._getChildApi(msg);
|
|
246
|
+
if (api) {
|
|
247
|
+
if (filterFn && !filterFn(api)) return result;
|
|
248
|
+
result.push(api);
|
|
230
249
|
}
|
|
231
|
-
|
|
250
|
+
return result;
|
|
251
|
+
}, []);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
proto.discard = function discard() {
|
|
255
|
+
this[kStatus] = 'discard';
|
|
256
|
+
return this[kActivityQ].queueMessage({routingKey: 'execution.discard'}, {
|
|
257
|
+
id: this.id,
|
|
258
|
+
type: this.type,
|
|
259
|
+
executionId: this.executionId,
|
|
260
|
+
}, {type: 'discard'});
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
proto.getState = function getState() {
|
|
265
|
+
const {children, flows, outboundMessageFlows, associations} = this[kElements];
|
|
266
|
+
return {
|
|
267
|
+
executionId: this.executionId,
|
|
268
|
+
stopped: this[kStopped],
|
|
269
|
+
completed: this[kCompleted],
|
|
270
|
+
status: this.status,
|
|
271
|
+
children: children.reduce((result, activity) => {
|
|
272
|
+
if (activity.placeholder) return result;
|
|
273
|
+
result.push(activity.getState());
|
|
274
|
+
return result;
|
|
275
|
+
}, []),
|
|
276
|
+
...(flows.length && {flows: flows.map((f) => f.getState())}),
|
|
277
|
+
...(outboundMessageFlows.length && {messageFlows: outboundMessageFlows.length && outboundMessageFlows.map((f) => f.getState())}),
|
|
278
|
+
...(associations.length && {associations: associations.map((f) => f.getState())}),
|
|
279
|
+
};
|
|
280
|
+
};
|
|
232
281
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
282
|
+
proto.getActivities = function getActivities() {
|
|
283
|
+
return this[kElements].children.slice();
|
|
284
|
+
};
|
|
236
285
|
|
|
237
|
-
|
|
238
|
-
|
|
286
|
+
proto.getActivityById = function getActivityById(activityId) {
|
|
287
|
+
return this[kElements].children.find((child) => child.id === activityId);
|
|
288
|
+
};
|
|
239
289
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
});
|
|
290
|
+
proto.getSequenceFlows = function getSequenceFlows() {
|
|
291
|
+
return this[kElements].flows.slice();
|
|
292
|
+
};
|
|
244
293
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
});
|
|
294
|
+
proto.getApi = function getApi(message) {
|
|
295
|
+
if (!message) return ProcessApi(this.broker, this[kExecuteMessage]);
|
|
248
296
|
|
|
249
|
-
|
|
250
|
-
association.broker.subscribeTmp('event', '#', onActivityEvent, {consumerTag: '_process-association-controller', noAck: true, priority: 200});
|
|
251
|
-
});
|
|
297
|
+
const content = message.content;
|
|
252
298
|
|
|
253
|
-
|
|
254
|
-
|
|
299
|
+
if (content.executionId !== this.executionId) {
|
|
300
|
+
return this._getChildApi(message);
|
|
301
|
+
}
|
|
255
302
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
activity.broker.subscribeTmp('event', '#', onActivityEvent, {noAck: true, consumerTag: '_process-activity-consumer', priority: 200});
|
|
260
|
-
if (activity.isStart) startActivities.push(activity);
|
|
261
|
-
if (activity.triggeredByEvent) triggeredByEventActivities.push(activity);
|
|
262
|
-
});
|
|
303
|
+
const api = ProcessApi(this.broker, message);
|
|
304
|
+
const postponed = this[kElements].postponed;
|
|
305
|
+
const self = this;
|
|
263
306
|
|
|
264
|
-
|
|
307
|
+
api.getExecuting = function getExecuting() {
|
|
308
|
+
return postponed.reduce((result, msg) => {
|
|
309
|
+
const childApi = self._getChildApi(msg);
|
|
310
|
+
if (childApi) result.push(childApi);
|
|
311
|
+
return result;
|
|
312
|
+
}, []);
|
|
313
|
+
};
|
|
265
314
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (message.fields.redelivered && message.properties.persistent === false) return;
|
|
315
|
+
return api;
|
|
316
|
+
};
|
|
269
317
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
318
|
+
proto._start = function start() {
|
|
319
|
+
if (this[kElements].children.length === 0) {
|
|
320
|
+
return this._complete('completed');
|
|
321
|
+
}
|
|
274
322
|
|
|
275
|
-
|
|
276
|
-
if (isDirectChild) {
|
|
277
|
-
parent.executionId = executionId;
|
|
278
|
-
} else {
|
|
279
|
-
content.parent = pushParent(parent, {id, type, executionId});
|
|
280
|
-
}
|
|
323
|
+
this[kStatus] = 'start';
|
|
281
324
|
|
|
282
|
-
|
|
325
|
+
const executeContent = {...this[kExecuteMessage].content, state: this.status};
|
|
283
326
|
|
|
284
|
-
|
|
285
|
-
if (shaking) return onShookEnd(message);
|
|
286
|
-
if (!isDirectChild) return;
|
|
287
|
-
if (content.isAssociation) return;
|
|
327
|
+
this.broker.publish(this._exchangeName, 'execute.start', cloneContent(executeContent));
|
|
288
328
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
case 'activity.stop':
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
activityQ.queueMessage(message.fields, cloneContent(content), {persistent: true, ...message.properties});
|
|
297
|
-
}
|
|
329
|
+
const {startActivities, postponed, detachedActivities} = this[kElements];
|
|
330
|
+
if (startActivities.length > 1) {
|
|
331
|
+
for (const a of startActivities) a.shake();
|
|
298
332
|
}
|
|
299
333
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
334
|
+
for (const a of startActivities) a.init();
|
|
335
|
+
for (const a of startActivities) a.run();
|
|
336
|
+
|
|
337
|
+
postponed.splice(0);
|
|
338
|
+
detachedActivities.splice(0);
|
|
339
|
+
this[kActivityQ].assertConsumer(this[kMessageHandlers].onChildMessage, {
|
|
340
|
+
prefetch: 1000,
|
|
341
|
+
consumerTag: `_process-activity-${this.executionId}`,
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
proto._activate = function activate() {
|
|
346
|
+
const {onApiMessage, onMessageFlowEvent, onActivityEvent} = this[kMessageHandlers];
|
|
347
|
+
|
|
348
|
+
this.broker.subscribeTmp('api', '#', onApiMessage, {
|
|
349
|
+
noAck: true,
|
|
350
|
+
consumerTag: `_process-api-consumer-${this.executionId}`,
|
|
351
|
+
priority: 200,
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
const {outboundMessageFlows, flows, associations, startActivities, triggeredByEvent, children} = this[kElements];
|
|
355
|
+
|
|
356
|
+
for (const flow of outboundMessageFlows) {
|
|
357
|
+
flow.activate();
|
|
358
|
+
flow.broker.subscribeTmp('event', '#', onMessageFlowEvent, {
|
|
359
|
+
consumerTag: '_process-message-consumer',
|
|
360
|
+
noAck: true,
|
|
361
|
+
priority: 200,
|
|
308
362
|
});
|
|
363
|
+
}
|
|
309
364
|
|
|
310
|
-
|
|
311
|
-
|
|
365
|
+
for (const flow of flows) {
|
|
366
|
+
flow.broker.subscribeTmp('event', '#', onActivityEvent, {
|
|
367
|
+
consumerTag: '_process-flow-controller',
|
|
368
|
+
noAck: true,
|
|
369
|
+
priority: 200,
|
|
312
370
|
});
|
|
371
|
+
}
|
|
313
372
|
|
|
314
|
-
|
|
315
|
-
|
|
373
|
+
for (const association of associations) {
|
|
374
|
+
association.broker.subscribeTmp('event', '#', onActivityEvent, {
|
|
375
|
+
consumerTag: '_process-association-controller',
|
|
376
|
+
noAck: true,
|
|
377
|
+
priority: 200,
|
|
316
378
|
});
|
|
379
|
+
}
|
|
317
380
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
flow.broker.cancel('_process-message-consumer');
|
|
321
|
-
});
|
|
381
|
+
startActivities.splice(0);
|
|
382
|
+
triggeredByEvent.splice(0);
|
|
322
383
|
|
|
323
|
-
|
|
384
|
+
for (const activity of children) {
|
|
385
|
+
if (activity.placeholder) continue;
|
|
386
|
+
activity.activate(this);
|
|
387
|
+
activity.broker.subscribeTmp('event', '#', onActivityEvent, {
|
|
388
|
+
noAck: true,
|
|
389
|
+
consumerTag: '_process-activity-consumer',
|
|
390
|
+
priority: 200,
|
|
391
|
+
});
|
|
392
|
+
if (activity.isStart) startActivities.push(activity);
|
|
393
|
+
if (activity.triggeredByEvent) triggeredByEvent.push(activity);
|
|
324
394
|
}
|
|
325
395
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
let delegate = true;
|
|
396
|
+
this[kActivated] = true;
|
|
397
|
+
};
|
|
329
398
|
|
|
330
|
-
|
|
331
|
-
|
|
399
|
+
proto._deactivate = function deactivate() {
|
|
400
|
+
const broker = this.broker;
|
|
401
|
+
const executionId = this.executionId;
|
|
402
|
+
broker.cancel(`_process-api-consumer-${executionId}`);
|
|
403
|
+
broker.cancel(`_process-activity-${executionId}`);
|
|
332
404
|
|
|
333
|
-
|
|
334
|
-
if (activity.getStartActivities({referenceId: content.message && content.message.id, referenceType: eventType}).length) {
|
|
335
|
-
delegate = false;
|
|
336
|
-
activity.run(content.message);
|
|
337
|
-
}
|
|
338
|
-
});
|
|
405
|
+
const {children, flows, associations, outboundMessageFlows} = this[kElements];
|
|
339
406
|
|
|
340
|
-
|
|
407
|
+
for (const activity of children) {
|
|
408
|
+
if (activity.placeholder) continue;
|
|
409
|
+
activity.broker.cancel('_process-activity-consumer');
|
|
410
|
+
activity.deactivate();
|
|
411
|
+
}
|
|
341
412
|
|
|
342
|
-
|
|
413
|
+
for (const flow of flows) {
|
|
414
|
+
flow.broker.cancel('_process-flow-controller');
|
|
343
415
|
}
|
|
344
416
|
|
|
345
|
-
|
|
346
|
-
broker.
|
|
417
|
+
for (const association of associations) {
|
|
418
|
+
association.broker.cancel('_process-association-controller');
|
|
347
419
|
}
|
|
348
420
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
const {persistent} = message.properties;
|
|
421
|
+
for (const flow of outboundMessageFlows) {
|
|
422
|
+
flow.deactivate();
|
|
423
|
+
flow.broker.cancel('_process-message-consumer');
|
|
424
|
+
}
|
|
354
425
|
|
|
355
|
-
|
|
426
|
+
this[kActivated] = false;
|
|
427
|
+
};
|
|
356
428
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
return stopExecution();
|
|
361
|
-
case 'execution.terminate':
|
|
362
|
-
message.ack();
|
|
363
|
-
return terminate(message);
|
|
364
|
-
case 'execution.discard':
|
|
365
|
-
message.ack();
|
|
366
|
-
return onDiscard(message);
|
|
367
|
-
case 'activity.compensation.end':
|
|
368
|
-
case 'flow.looped':
|
|
369
|
-
case 'activity.leave':
|
|
370
|
-
return onChildCompleted();
|
|
371
|
-
}
|
|
429
|
+
proto._onDelegateEvent = function onDelegateEvent(message) {
|
|
430
|
+
const eventType = message.properties.type;
|
|
431
|
+
let delegate = true;
|
|
372
432
|
|
|
373
|
-
|
|
433
|
+
const content = message.content;
|
|
434
|
+
if (content.message && content.message.id) {
|
|
435
|
+
this._debug(`delegate ${eventType} event with id <${content.message.id}>`);
|
|
436
|
+
} else {
|
|
437
|
+
this._debug(`delegate ${eventType} anonymous event`);
|
|
438
|
+
}
|
|
374
439
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
case 'activity.discard':
|
|
381
|
-
case 'activity.compensation.start':
|
|
382
|
-
case 'activity.enter': {
|
|
383
|
-
status = 'executing';
|
|
384
|
-
popInbound();
|
|
385
|
-
break;
|
|
386
|
-
}
|
|
387
|
-
case 'flow.error':
|
|
388
|
-
case 'activity.error': {
|
|
389
|
-
if (isEventCaught()) {
|
|
390
|
-
logger.debug(`<${executionName}> error was caught`);
|
|
391
|
-
break;
|
|
392
|
-
}
|
|
393
|
-
complete('error', {error: content.error});
|
|
394
|
-
break;
|
|
395
|
-
}
|
|
440
|
+
for (const activity of this[kElements].triggeredByEvent) {
|
|
441
|
+
if (activity.getStartActivities({referenceId: content.message && content.message.id, referenceType: eventType}).length) {
|
|
442
|
+
delegate = false;
|
|
443
|
+
activity.run(content.message);
|
|
396
444
|
}
|
|
445
|
+
}
|
|
397
446
|
|
|
398
|
-
|
|
399
|
-
const previousMsg = popPostponed(content);
|
|
400
|
-
if (previousMsg) previousMsg.ack();
|
|
401
|
-
if (postponeMessage) postponed.push(message);
|
|
402
|
-
}
|
|
447
|
+
this.getApi().sendApiMessage(eventType, content, {delegate: true});
|
|
403
448
|
|
|
404
|
-
|
|
405
|
-
|
|
449
|
+
return delegate;
|
|
450
|
+
};
|
|
406
451
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
if (msg) msg.ack();
|
|
411
|
-
});
|
|
412
|
-
}
|
|
452
|
+
proto._onMessageFlowEvent = function onMessageFlowEvent(routingKey, message) {
|
|
453
|
+
this.broker.publish('message', routingKey, cloneContent(message.content), message.properties);
|
|
454
|
+
};
|
|
413
455
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
if (msg.content.isSequenceFlow) return msg.content.sequenceId === byContent.sequenceId;
|
|
417
|
-
return msg.content.executionId === byContent.executionId;
|
|
418
|
-
});
|
|
456
|
+
proto._onActivityEvent = function onActivityEvent(routingKey, message) {
|
|
457
|
+
if (message.fields.redelivered && message.properties.persistent === false) return;
|
|
419
458
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
459
|
+
const content = message.content;
|
|
460
|
+
const parent = content.parent = content.parent || {};
|
|
461
|
+
let delegate = message.properties.delegate;
|
|
462
|
+
const shaking = message.properties.type === 'shake';
|
|
424
463
|
|
|
425
|
-
|
|
426
|
-
|
|
464
|
+
const isDirectChild = content.parent.id === this.id;
|
|
465
|
+
if (isDirectChild) {
|
|
466
|
+
parent.executionId = this.executionId;
|
|
467
|
+
} else {
|
|
468
|
+
content.parent = pushParent(parent, {id: this.id, type: this.type, executionId: this.executionId});
|
|
469
|
+
}
|
|
427
470
|
|
|
428
|
-
|
|
429
|
-
}
|
|
471
|
+
if (delegate) delegate = this._onDelegateEvent(message);
|
|
430
472
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
473
|
+
this.broker.publish('event', routingKey, content, {...message.properties, delegate, mandatory: false});
|
|
474
|
+
if (shaking) return this._onShookEnd(message);
|
|
475
|
+
if (!isDirectChild) return;
|
|
476
|
+
if (content.isAssociation) return;
|
|
434
477
|
|
|
435
|
-
|
|
478
|
+
switch (routingKey) {
|
|
479
|
+
case 'process.terminate':
|
|
480
|
+
return this[kActivityQ].queueMessage({routingKey: 'execution.terminate'}, cloneContent(content), {type: 'terminate', persistent: true});
|
|
481
|
+
case 'activity.stop':
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
436
484
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
485
|
+
this[kActivityQ].queueMessage(message.fields, cloneContent(content), {persistent: true, ...message.properties});
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
proto._onChildMessage = function onChildMessage(routingKey, message) {
|
|
489
|
+
if (message.fields.redelivered && message.properties.persistent === false) return message.ack();
|
|
490
|
+
|
|
491
|
+
const content = message.content;
|
|
492
|
+
|
|
493
|
+
switch (routingKey) {
|
|
494
|
+
case 'execution.stop':
|
|
495
|
+
message.ack();
|
|
496
|
+
return this._stopExecution(message);
|
|
497
|
+
case 'execution.terminate':
|
|
498
|
+
message.ack();
|
|
499
|
+
return this._terminate(message);
|
|
500
|
+
case 'execution.discard':
|
|
501
|
+
message.ack();
|
|
502
|
+
return this._onDiscard(message);
|
|
503
|
+
case 'activity.compensation.end':
|
|
504
|
+
case 'flow.looped':
|
|
505
|
+
case 'activity.leave':
|
|
506
|
+
return this._onChildCompleted(message);
|
|
507
|
+
}
|
|
447
508
|
|
|
448
|
-
|
|
449
|
-
for (const p of postponed) {
|
|
450
|
-
const postponedId = p.content.id;
|
|
451
|
-
const startSequence = startSequences[postponedId];
|
|
452
|
-
if (startSequence) {
|
|
453
|
-
if (startSequence.content.sequence.some(({id: sid}) => sid === childId)) {
|
|
454
|
-
getApi(p).discard();
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
509
|
+
this._stateChangeMessage(message, true);
|
|
459
510
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
api.stop();
|
|
465
|
-
});
|
|
466
|
-
deactivate();
|
|
467
|
-
stopped = true;
|
|
468
|
-
return broker.publish(exchangeName, `execution.stopped.${executionId}`, {
|
|
469
|
-
...stateMessage.content,
|
|
470
|
-
...content,
|
|
471
|
-
}, {type: 'stopped', persistent: false});
|
|
511
|
+
switch (routingKey) {
|
|
512
|
+
case 'activity.detach': {
|
|
513
|
+
this[kElements].detachedActivities.push(cloneMessage(message));
|
|
514
|
+
break;
|
|
472
515
|
}
|
|
516
|
+
case 'activity.discard':
|
|
517
|
+
case 'activity.compensation.start':
|
|
518
|
+
case 'activity.enter': {
|
|
519
|
+
this[kStatus] = 'executing';
|
|
520
|
+
if (!content.inbound) break;
|
|
521
|
+
|
|
522
|
+
for (const inbound of content.inbound) {
|
|
523
|
+
if (!inbound.isSequenceFlow) continue;
|
|
524
|
+
const inboundMessage = this._popPostponed(inbound);
|
|
525
|
+
if (inboundMessage) inboundMessage.ack();
|
|
526
|
+
}
|
|
473
527
|
|
|
474
|
-
|
|
475
|
-
deactivate();
|
|
476
|
-
const running = postponed.splice(0);
|
|
477
|
-
logger.debug(`<${executionName}> discard process execution (discard child executions ${running.length})`);
|
|
478
|
-
|
|
479
|
-
getSequenceFlows().forEach((flow) => {
|
|
480
|
-
flow.stop();
|
|
481
|
-
});
|
|
482
|
-
|
|
483
|
-
running.forEach((msg) => {
|
|
484
|
-
getApi(msg).discard();
|
|
485
|
-
});
|
|
486
|
-
|
|
487
|
-
activityQ.purge();
|
|
488
|
-
return complete('discard');
|
|
528
|
+
break;
|
|
489
529
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
return postponed.find((msg) => {
|
|
530
|
+
case 'activity.error': {
|
|
531
|
+
const eventCaughtBy = this[kElements].postponed.find((msg) => {
|
|
493
532
|
if (msg.fields.routingKey !== 'activity.catch') return;
|
|
494
533
|
return msg.content.source && msg.content.source.executionId === content.executionId;
|
|
495
534
|
});
|
|
535
|
+
if (eventCaughtBy) {
|
|
536
|
+
return this._debug('error was caught');
|
|
537
|
+
}
|
|
538
|
+
return this._complete('error', {error: content.error});
|
|
496
539
|
}
|
|
497
540
|
}
|
|
541
|
+
};
|
|
498
542
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
543
|
+
proto._stateChangeMessage = function stateChangeMessage(message, postponeMessage) {
|
|
544
|
+
const previousMsg = this._popPostponed(message.content);
|
|
545
|
+
if (previousMsg) previousMsg.ack();
|
|
546
|
+
if (postponeMessage) this[kElements].postponed.push(message);
|
|
547
|
+
};
|
|
503
548
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
if (!child) return null;
|
|
507
|
-
return child.broker.publish('api', routingKey, message.content, message.properties);
|
|
508
|
-
}
|
|
549
|
+
proto._popPostponed = function popPostponed(byContent) {
|
|
550
|
+
const {postponed, detachedActivities} = this[kElements];
|
|
509
551
|
|
|
510
|
-
|
|
552
|
+
const postponedIdx = postponed.findIndex((msg) => {
|
|
553
|
+
if (msg.content.isSequenceFlow) return msg.content.sequenceId === byContent.sequenceId;
|
|
554
|
+
return msg.content.executionId === byContent.executionId;
|
|
555
|
+
});
|
|
511
556
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
case 'stop':
|
|
516
|
-
activityQ.queueMessage({routingKey: 'execution.stop'}, cloneContent(message.content), {persistent: false});
|
|
517
|
-
break;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function delegateApiMessage() {
|
|
521
|
-
const {correlationId} = message.properties || getUniqueId(executionId);
|
|
522
|
-
logger.debug(`<${executionName}> delegate api`, routingKey, `message to children, with correlationId <${correlationId}>`);
|
|
523
|
-
|
|
524
|
-
let consumed = false;
|
|
525
|
-
broker.subscribeTmp('event', 'activity.consumed', (_, msg) => {
|
|
526
|
-
if (msg.properties.correlationId === correlationId) {
|
|
527
|
-
consumed = true;
|
|
528
|
-
logger.debug(`<${executionName}> delegated api message was consumed by`, msg.content ? msg.content.executionId : 'unknown');
|
|
529
|
-
}
|
|
530
|
-
}, {consumerTag: `_ct-delegate-${correlationId}`, noAck: true});
|
|
531
|
-
|
|
532
|
-
for (const child of children) {
|
|
533
|
-
if (child.placeholder) continue;
|
|
534
|
-
child.broker.publish('api', routingKey, cloneContent(message.content), message.properties);
|
|
535
|
-
if (consumed) break;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
broker.cancel(`_ct-delegate-${correlationId}`);
|
|
539
|
-
}
|
|
557
|
+
let postponedMsg;
|
|
558
|
+
if (postponedIdx > -1) {
|
|
559
|
+
postponedMsg = postponed.splice(postponedIdx, 1)[0];
|
|
540
560
|
}
|
|
541
561
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
const api = getApi(p);
|
|
545
|
-
if (api) {
|
|
546
|
-
if (filterFn && !filterFn(api)) return result;
|
|
547
|
-
result.push(api);
|
|
548
|
-
}
|
|
549
|
-
return result;
|
|
550
|
-
}, []);
|
|
551
|
-
}
|
|
562
|
+
const detachedIdx = detachedActivities.findIndex((msg) => msg.content.executionId === byContent.executionId);
|
|
563
|
+
if (detachedIdx > -1) detachedActivities.splice(detachedIdx, 1);
|
|
552
564
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
logger.debug(`<${executionName}> process execution ${completionType}`);
|
|
556
|
-
completed = true;
|
|
557
|
-
if (status !== 'terminated') status = completionType;
|
|
558
|
-
broker.deleteQueue(activityQ.name);
|
|
565
|
+
return postponedMsg;
|
|
566
|
+
};
|
|
559
567
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
...content,
|
|
564
|
-
state: completionType,
|
|
565
|
-
}, {type: completionType, mandatory: completionType === 'error'});
|
|
566
|
-
}
|
|
568
|
+
proto._onChildCompleted = function onChildCompleted(message) {
|
|
569
|
+
this._stateChangeMessage(message, false);
|
|
570
|
+
if (message.fields.redelivered) return message.ack();
|
|
567
571
|
|
|
568
|
-
|
|
569
|
-
status = 'discard';
|
|
570
|
-
return activityQ.queueMessage({routingKey: 'execution.discard'}, {
|
|
571
|
-
id,
|
|
572
|
-
type,
|
|
573
|
-
executionId,
|
|
574
|
-
}, {type: 'discard'});
|
|
575
|
-
}
|
|
572
|
+
const {id, type, isEnd} = message.content;
|
|
576
573
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
logger.debug(`<${executionName}> terminating process execution`);
|
|
574
|
+
const {postponed, detachedActivities, startActivities} = this[kElements];
|
|
575
|
+
const postponedCount = postponed.length;
|
|
580
576
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
577
|
+
if (!postponedCount) {
|
|
578
|
+
this._debug(`left <${id}> (${type}), pending runs ${postponedCount}`);
|
|
579
|
+
message.ack();
|
|
580
|
+
return this._complete('completed');
|
|
581
|
+
}
|
|
585
582
|
|
|
586
|
-
|
|
587
|
-
const {id: postponedId, isSequenceFlow} = msg.content;
|
|
588
|
-
if (postponedId === message.content.id) return;
|
|
589
|
-
if (isSequenceFlow) return;
|
|
590
|
-
getApi(msg).stop();
|
|
591
|
-
msg.ack();
|
|
592
|
-
});
|
|
583
|
+
this._debug(`left <${id}> (${type}), pending runs ${postponedCount}, ${postponed.map((a) => a.content.id).join(',')}`);
|
|
593
584
|
|
|
594
|
-
|
|
585
|
+
if (postponedCount === detachedActivities.length) {
|
|
586
|
+
for (const api of this.getPostponed()) api.discard();
|
|
587
|
+
return;
|
|
595
588
|
}
|
|
596
589
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
flows: flows.map((f) => f.getState()),
|
|
609
|
-
messageFlows: outboundMessageFlows.map((f) => f.getState()),
|
|
610
|
-
associations: associations.map((f) => f.getState()),
|
|
611
|
-
};
|
|
590
|
+
if (isEnd && startActivities.length) {
|
|
591
|
+
const startSequences = this[kElements].startSequences;
|
|
592
|
+
for (const msg of postponed) {
|
|
593
|
+
const postponedId = msg.content.id;
|
|
594
|
+
const startSequence = startSequences[postponedId];
|
|
595
|
+
if (startSequence) {
|
|
596
|
+
if (startSequence.content.sequence.some(({id: sid}) => sid === id)) {
|
|
597
|
+
this._getChildApi(msg).discard();
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
612
601
|
}
|
|
602
|
+
};
|
|
613
603
|
|
|
614
|
-
|
|
615
|
-
|
|
604
|
+
proto._stopExecution = function stopExecution(message) {
|
|
605
|
+
const postponedCount = this.postponedCount;
|
|
606
|
+
this._debug(`stop process execution (stop child executions ${postponedCount})`);
|
|
607
|
+
if (postponedCount) {
|
|
608
|
+
for (const api of this.getPostponed()) api.stop();
|
|
616
609
|
}
|
|
610
|
+
this._deactivate();
|
|
611
|
+
this[kStopped] = true;
|
|
612
|
+
return this.broker.publish(this._exchangeName, `execution.stopped.${this.executionId}`, {
|
|
613
|
+
...this[kExecuteMessage].content,
|
|
614
|
+
...(message && message.content),
|
|
615
|
+
}, {type: 'stopped', persistent: false});
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
proto._onDiscard = function onDiscard() {
|
|
619
|
+
this._deactivate();
|
|
620
|
+
const running = this[kElements].postponed.splice(0);
|
|
621
|
+
this._debug(`discard process execution (discard child executions ${running.length})`);
|
|
622
|
+
|
|
623
|
+
for (const flow of this.getSequenceFlows()) flow.stop();
|
|
624
|
+
for (const msg of running) this._getChildApi(msg).discard();
|
|
625
|
+
|
|
626
|
+
this[kActivityQ].purge();
|
|
627
|
+
return this._complete('discard');
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
proto._onApiMessage = function onApiMessage(routingKey, message) {
|
|
631
|
+
const executionId = this.executionId;
|
|
632
|
+
const broker = this.broker;
|
|
633
|
+
if (message.properties.delegate) {
|
|
634
|
+
const correlationId = message.properties.correlationId || getUniqueId(executionId);
|
|
635
|
+
this._debug(`delegate api ${routingKey} message to children, with correlationId <${correlationId}>`);
|
|
636
|
+
|
|
637
|
+
let consumed = false;
|
|
638
|
+
broker.subscribeTmp('event', 'activity.consumed', (_, msg) => {
|
|
639
|
+
if (msg.properties.correlationId === correlationId) {
|
|
640
|
+
consumed = true;
|
|
641
|
+
this._debug(`delegated api message was consumed by ${msg.content ? msg.content.executionId : 'unknown'}`);
|
|
642
|
+
}
|
|
643
|
+
}, {consumerTag: `_ct-delegate-${correlationId}`, noAck: true});
|
|
617
644
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
645
|
+
for (const child of this[kElements].children) {
|
|
646
|
+
if (child.placeholder) continue;
|
|
647
|
+
child.broker.publish('api', routingKey, cloneContent(message.content), message.properties);
|
|
648
|
+
if (consumed) break;
|
|
649
|
+
}
|
|
621
650
|
|
|
622
|
-
|
|
623
|
-
return flows.find((f) => f.id === flowId);
|
|
651
|
+
return broker.cancel(`_ct-delegate-${correlationId}`);
|
|
624
652
|
}
|
|
625
653
|
|
|
626
|
-
|
|
627
|
-
|
|
654
|
+
if (this.id !== message.content.id) {
|
|
655
|
+
const child = this.getActivityById(message.content.id);
|
|
656
|
+
if (!child) return null;
|
|
657
|
+
return child.broker.publish('api', routingKey, message.content, message.properties);
|
|
628
658
|
}
|
|
629
659
|
|
|
630
|
-
|
|
631
|
-
return outboundMessageFlows.find((f) => f.id === flowId);
|
|
632
|
-
}
|
|
660
|
+
if (this.executionId !== message.content.executionId) return;
|
|
633
661
|
|
|
634
|
-
|
|
635
|
-
|
|
662
|
+
switch (message.properties.type) {
|
|
663
|
+
case 'discard':
|
|
664
|
+
return this.discard(message);
|
|
665
|
+
case 'stop':
|
|
666
|
+
this[kActivityQ].queueMessage({routingKey: 'execution.stop'}, cloneContent(message.content), {persistent: false});
|
|
667
|
+
break;
|
|
636
668
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
proto._complete = function complete(completionType, content) {
|
|
672
|
+
this._deactivate();
|
|
673
|
+
this._debug(`process execution ${completionType}`);
|
|
674
|
+
this[kCompleted] = true;
|
|
675
|
+
if (this.status !== 'terminated') this[kStatus] = completionType;
|
|
676
|
+
const broker = this.broker;
|
|
677
|
+
this[kActivityQ].delete();
|
|
678
|
+
|
|
679
|
+
return broker.publish(this._exchangeName, `execution.${completionType}.${this.executionId}`, cloneContent(this[kExecuteMessage].content, {
|
|
680
|
+
output: {...this.environment.output},
|
|
681
|
+
...content,
|
|
682
|
+
state: completionType,
|
|
683
|
+
}), {type: completionType, mandatory: completionType === 'error'});
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
proto._terminate = function terminate(message) {
|
|
687
|
+
this[kStatus] = 'terminated';
|
|
688
|
+
this._debug('terminating process execution');
|
|
689
|
+
|
|
690
|
+
const running = this[kElements].postponed.splice(0);
|
|
691
|
+
for (const flow of this.getSequenceFlows()) flow.stop();
|
|
692
|
+
|
|
693
|
+
for (const msg of running) {
|
|
694
|
+
const {id: postponedId, isSequenceFlow} = msg.content;
|
|
695
|
+
if (postponedId === message.content.id) continue;
|
|
696
|
+
if (isSequenceFlow) continue;
|
|
697
|
+
this._getChildApi(msg).stop();
|
|
698
|
+
msg.ack();
|
|
640
699
|
}
|
|
641
700
|
|
|
642
|
-
|
|
643
|
-
|
|
701
|
+
this[kActivityQ].purge();
|
|
702
|
+
};
|
|
644
703
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
const api = ProcessApi(broker, message);
|
|
704
|
+
proto._getFlowById = function getFlowById(flowId) {
|
|
705
|
+
return this[kElements].flows.find((f) => f.id === flowId);
|
|
706
|
+
};
|
|
651
707
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
result.push(getApi(msg));
|
|
656
|
-
return result;
|
|
657
|
-
}, []);
|
|
658
|
-
};
|
|
708
|
+
proto._getAssociationById = function getAssociationById(associationId) {
|
|
709
|
+
return this[kElements].associations.find((a) => a.id === associationId);
|
|
710
|
+
};
|
|
659
711
|
|
|
660
|
-
|
|
661
|
-
|
|
712
|
+
proto._getMessageFlowById = function getMessageFlowById(flowId) {
|
|
713
|
+
return this[kElements].outboundMessageFlows.find((f) => f.id === flowId);
|
|
714
|
+
};
|
|
662
715
|
|
|
663
|
-
|
|
664
|
-
|
|
716
|
+
proto._getChildById = function getChildById(childId) {
|
|
717
|
+
return this.getActivityById(childId) || this._getFlowById(childId);
|
|
718
|
+
};
|
|
665
719
|
|
|
666
|
-
|
|
667
|
-
|
|
720
|
+
proto._getChildApi = function getChildApi(message) {
|
|
721
|
+
const content = message.content;
|
|
668
722
|
|
|
669
|
-
|
|
723
|
+
let child = this._getChildById(content.id);
|
|
724
|
+
if (child) return child.getApi(message);
|
|
670
725
|
|
|
671
|
-
|
|
672
|
-
if (api) return api;
|
|
726
|
+
if (!content.parent) return;
|
|
673
727
|
|
|
674
|
-
|
|
728
|
+
child = this._getChildById(content.parent.id);
|
|
729
|
+
if (child) return child.getApi(message);
|
|
675
730
|
|
|
676
|
-
|
|
677
|
-
api = getApiByChildId(content.parent.path[i].id);
|
|
678
|
-
if (api) return api;
|
|
679
|
-
}
|
|
731
|
+
if (!content.parent.path) return;
|
|
680
732
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
return child.getApi(message);
|
|
685
|
-
}
|
|
733
|
+
for (const pp of content.parent.path) {
|
|
734
|
+
child = this._getChildById(pp.id, message);
|
|
735
|
+
if (child) return child.getApi(message);
|
|
686
736
|
}
|
|
737
|
+
};
|
|
687
738
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
739
|
+
proto._onShookEnd = function onShookEnd(message) {
|
|
740
|
+
const routingKey = message.fields.routingKey;
|
|
741
|
+
if (routingKey !== 'activity.shake.end') return;
|
|
742
|
+
this[kElements].startSequences[message.content.id] = cloneMessage(message);
|
|
743
|
+
};
|
|
693
744
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
}
|
|
745
|
+
proto._debug = function debugMessage(logMessage) {
|
|
746
|
+
this[kParent].logger.debug(`<${this.executionId} (${this.id})> ${logMessage}`);
|
|
747
|
+
};
|