bpmn-elements 6.0.1 → 7.0.0
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 +322 -0
- package/README.md +3 -0
- package/dist/index.js +52 -44
- package/dist/src/Api.js +77 -76
- package/dist/src/Context.js +169 -175
- package/dist/src/Environment.js +90 -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 +1106 -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 +722 -409
- 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 +433 -359
- package/dist/src/process/ProcessExecution.js +744 -645
- 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 +195 -175
- package/dist/src/tasks/Task.js +17 -19
- package/index.js +2 -0
- package/package.json +13 -13
- package/src/Api.js +65 -59
- package/src/Context.js +138 -141
- package/src/Environment.js +88 -100
- package/src/EventBroker.js +67 -68
- package/src/ExtensionsMapper.js +2 -2
- package/src/MessageFormatter.js +132 -74
- package/src/activity/Activity.js +915 -775
- package/src/activity/ActivityExecution.js +293 -247
- package/src/activity/Dummy.js +2 -2
- package/src/definition/Definition.js +436 -401
- package/src/definition/DefinitionExecution.js +603 -343
- package/src/error/Errors.js +11 -6
- package/src/eventDefinitions/CancelEventDefinition.js +164 -121
- package/src/eventDefinitions/CompensateEventDefinition.js +158 -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 +16 -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 +374 -333
- package/src/process/ProcessExecution.js +606 -554
- 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,748 @@ 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 activatedSymbol = Symbol.for('activated');
|
|
8
|
+
const activityQSymbol = Symbol.for('activityQ');
|
|
9
|
+
const completedSymbol = Symbol.for('completed');
|
|
10
|
+
const elementsSymbol = Symbol.for('elements');
|
|
11
|
+
const executeMessageSymbol = Symbol.for('executeMessage');
|
|
12
|
+
const messageHandlersSymbol = Symbol.for('messageHandlers');
|
|
13
|
+
const parentSymbol = Symbol.for('parent');
|
|
14
|
+
const statusSymbol = Symbol.for('status');
|
|
15
|
+
const stoppedSymbol = Symbol.for('stopped');
|
|
16
|
+
|
|
17
|
+
function ProcessExecution(parentActivity, context) {
|
|
18
|
+
const {id, type, broker, isSubProcess} = parentActivity;
|
|
19
|
+
|
|
20
|
+
this[parentSymbol] = 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[elementsSymbol] = {
|
|
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[completedSymbol] = false;
|
|
44
|
+
this[stoppedSymbol] = false;
|
|
45
|
+
this[activatedSymbol] = false;
|
|
46
|
+
this[statusSymbol] = 'init';
|
|
47
|
+
this.executionId = undefined;
|
|
48
|
+
|
|
49
|
+
this[messageHandlersSymbol] = {
|
|
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[stoppedSymbol];
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
Object.defineProperty(proto, 'completed', {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get() {
|
|
69
|
+
return this[completedSymbol];
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
Object.defineProperty(proto, 'status', {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
get() {
|
|
76
|
+
return this[statusSymbol];
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
Object.defineProperty(proto, 'postponedCount', {
|
|
81
|
+
get() {
|
|
82
|
+
return this[elementsSymbol].postponed.length;
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
Object.defineProperty(proto, 'isRunning', {
|
|
87
|
+
get() {
|
|
88
|
+
return this[activatedSymbol];
|
|
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[executeMessageSymbol] = cloneMessage(executeMessage, {
|
|
99
|
+
executionId,
|
|
100
|
+
state: 'start',
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
this[stoppedSymbol] = false;
|
|
104
|
+
|
|
105
|
+
this.environment.assignVariables(executeMessage);
|
|
106
|
+
this[activityQSymbol] = 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[completedSymbol]) 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[elementsSymbol];
|
|
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[activityQSymbol].consume(this[messageHandlersSymbol].onChildMessage, {
|
|
135
|
+
prefetch: 1000,
|
|
136
|
+
consumerTag: `_process-activity-${this.executionId}`,
|
|
137
|
+
});
|
|
133
138
|
|
|
134
|
-
|
|
139
|
+
if (this[completedSymbol]) return this._complete('completed');
|
|
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[stoppedSymbol] = state.stopped;
|
|
163
|
+
this[completedSymbol] = state.completed;
|
|
164
|
+
this[statusSymbol] = 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[elementsSymbol].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[elementsSymbol].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[statusSymbol] = 'discard';
|
|
256
|
+
return this[activityQSymbol].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 {flows, outboundMessageFlows, associations} = this[elementsSymbol];
|
|
266
|
+
return {
|
|
267
|
+
executionId: this.executionId,
|
|
268
|
+
stopped: this[stoppedSymbol],
|
|
269
|
+
completed: this[completedSymbol],
|
|
270
|
+
status: this.status,
|
|
271
|
+
children: this[elementsSymbol].children.reduce((result, activity) => {
|
|
272
|
+
if (activity.placeholder) return result;
|
|
273
|
+
result.push(activity.getState());
|
|
274
|
+
return result;
|
|
275
|
+
}, []),
|
|
276
|
+
flows: flows.map((f) => f.getState()),
|
|
277
|
+
messageFlows: outboundMessageFlows.map((f) => f.getState()),
|
|
278
|
+
associations: associations.map((f) => f.getState()),
|
|
279
|
+
};
|
|
280
|
+
};
|
|
232
281
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
282
|
+
proto.getActivities = function getActivities() {
|
|
283
|
+
return this[elementsSymbol].children.slice();
|
|
284
|
+
};
|
|
236
285
|
|
|
237
|
-
|
|
238
|
-
|
|
286
|
+
proto.getActivityById = function getActivityById(activityId) {
|
|
287
|
+
return this[elementsSymbol].children.find((child) => child.id === activityId);
|
|
288
|
+
};
|
|
239
289
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
});
|
|
290
|
+
proto.getSequenceFlows = function getSequenceFlows() {
|
|
291
|
+
return this[elementsSymbol].flows.slice();
|
|
292
|
+
};
|
|
244
293
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
});
|
|
294
|
+
proto.getApi = function getApi(message) {
|
|
295
|
+
if (!message) return ProcessApi(this.broker, this[executeMessageSymbol]);
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
children.forEach((activity) => {
|
|
257
|
-
if (activity.placeholder) return;
|
|
258
|
-
activity.activate(processExecution);
|
|
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
|
-
});
|
|
299
|
+
if (content.executionId !== this.executionId) {
|
|
300
|
+
return this._getChildApi(message);
|
|
301
|
+
}
|
|
263
302
|
|
|
264
|
-
|
|
303
|
+
const api = ProcessApi(this.broker, message);
|
|
304
|
+
const postponed = this[elementsSymbol].postponed;
|
|
305
|
+
const self = this;
|
|
265
306
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
+
};
|
|
269
314
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
let delegate = message.properties.delegate;
|
|
273
|
-
const shaking = message.properties.type === 'shake';
|
|
315
|
+
return api;
|
|
316
|
+
};
|
|
274
317
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
content.parent = pushParent(parent, {id, type, executionId});
|
|
280
|
-
}
|
|
318
|
+
proto._start = function start() {
|
|
319
|
+
if (this[elementsSymbol].children.length === 0) {
|
|
320
|
+
return this._complete('completed');
|
|
321
|
+
}
|
|
281
322
|
|
|
282
|
-
|
|
323
|
+
this[statusSymbol] = 'start';
|
|
283
324
|
|
|
284
|
-
|
|
285
|
-
if (shaking) return onShookEnd(message);
|
|
286
|
-
if (!isDirectChild) return;
|
|
287
|
-
if (content.isAssociation) return;
|
|
325
|
+
const executeContent = {...this[executeMessageSymbol].content, state: this.status};
|
|
288
326
|
|
|
289
|
-
|
|
290
|
-
case 'process.terminate':
|
|
291
|
-
return activityQ.queueMessage({routingKey: 'execution.terminate'}, cloneContent(content), {type: 'terminate', persistent: true});
|
|
292
|
-
case 'activity.stop':
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
327
|
+
this.broker.publish(this._exchangeName, 'execute.start', cloneContent(executeContent));
|
|
295
328
|
|
|
296
|
-
|
|
297
|
-
|
|
329
|
+
const {startActivities, postponed, detachedActivities} = this[elementsSymbol];
|
|
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[activityQSymbol].assertConsumer(this[messageHandlersSymbol].onChildMessage, {
|
|
340
|
+
prefetch: 1000,
|
|
341
|
+
consumerTag: `_process-activity-${this.executionId}`,
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
proto._activate = function activate() {
|
|
346
|
+
const {onApiMessage, onMessageFlowEvent, onActivityEvent} = this[messageHandlersSymbol];
|
|
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[elementsSymbol];
|
|
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[activatedSymbol] = 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[elementsSymbol];
|
|
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[activatedSymbol] = 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[elementsSymbol].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[activityQSymbol].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[activityQSymbol].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[elementsSymbol].detachedActivities.push(cloneMessage(message));
|
|
514
|
+
break;
|
|
472
515
|
}
|
|
516
|
+
case 'activity.discard':
|
|
517
|
+
case 'activity.compensation.start':
|
|
518
|
+
case 'activity.enter': {
|
|
519
|
+
this[statusSymbol] = '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
|
-
|
|
530
|
+
case 'flow.error':
|
|
531
|
+
case 'activity.error': {
|
|
532
|
+
const eventCaughtBy = this[elementsSymbol].postponed.find((msg) => {
|
|
493
533
|
if (msg.fields.routingKey !== 'activity.catch') return;
|
|
494
534
|
return msg.content.source && msg.content.source.executionId === content.executionId;
|
|
495
535
|
});
|
|
536
|
+
if (eventCaughtBy) {
|
|
537
|
+
return this._debug('error was caught');
|
|
538
|
+
}
|
|
539
|
+
return this._complete('error', {error: content.error});
|
|
496
540
|
}
|
|
497
541
|
}
|
|
542
|
+
};
|
|
498
543
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
544
|
+
proto._stateChangeMessage = function stateChangeMessage(message, postponeMessage) {
|
|
545
|
+
const previousMsg = this._popPostponed(message.content);
|
|
546
|
+
if (previousMsg) previousMsg.ack();
|
|
547
|
+
if (postponeMessage) this[elementsSymbol].postponed.push(message);
|
|
548
|
+
};
|
|
503
549
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
if (!child) return null;
|
|
507
|
-
return child.broker.publish('api', routingKey, message.content, message.properties);
|
|
508
|
-
}
|
|
550
|
+
proto._popPostponed = function popPostponed(byContent) {
|
|
551
|
+
const {postponed, detachedActivities} = this[elementsSymbol];
|
|
509
552
|
|
|
510
|
-
|
|
553
|
+
const postponedIdx = postponed.findIndex((msg) => {
|
|
554
|
+
if (msg.content.isSequenceFlow) return msg.content.sequenceId === byContent.sequenceId;
|
|
555
|
+
return msg.content.executionId === byContent.executionId;
|
|
556
|
+
});
|
|
511
557
|
|
|
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
|
-
}
|
|
558
|
+
let postponedMsg;
|
|
559
|
+
if (postponedIdx > -1) {
|
|
560
|
+
postponedMsg = postponed.splice(postponedIdx, 1)[0];
|
|
540
561
|
}
|
|
541
562
|
|
|
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
|
-
}
|
|
563
|
+
const detachedIdx = detachedActivities.findIndex((msg) => msg.content.executionId === byContent.executionId);
|
|
564
|
+
if (detachedIdx > -1) detachedActivities.splice(detachedIdx, 1);
|
|
552
565
|
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
logger.debug(`<${executionName}> process execution ${completionType}`);
|
|
556
|
-
completed = true;
|
|
557
|
-
if (status !== 'terminated') status = completionType;
|
|
558
|
-
broker.deleteQueue(activityQ.name);
|
|
566
|
+
return postponedMsg;
|
|
567
|
+
};
|
|
559
568
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
...content,
|
|
564
|
-
state: completionType,
|
|
565
|
-
}, {type: completionType, mandatory: completionType === 'error'});
|
|
566
|
-
}
|
|
569
|
+
proto._onChildCompleted = function onChildCompleted(message) {
|
|
570
|
+
this._stateChangeMessage(message, false);
|
|
571
|
+
if (message.fields.redelivered) return message.ack();
|
|
567
572
|
|
|
568
|
-
|
|
569
|
-
status = 'discard';
|
|
570
|
-
return activityQ.queueMessage({routingKey: 'execution.discard'}, {
|
|
571
|
-
id,
|
|
572
|
-
type,
|
|
573
|
-
executionId,
|
|
574
|
-
}, {type: 'discard'});
|
|
575
|
-
}
|
|
573
|
+
const {id, type, isEnd} = message.content;
|
|
576
574
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
logger.debug(`<${executionName}> terminating process execution`);
|
|
575
|
+
const {postponed, detachedActivities, startActivities} = this[elementsSymbol];
|
|
576
|
+
const postponedCount = postponed.length;
|
|
580
577
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
578
|
+
if (!postponedCount) {
|
|
579
|
+
this._debug(`left <${id}> (${type}), pending runs ${postponedCount}`);
|
|
580
|
+
message.ack();
|
|
581
|
+
return this._complete('completed');
|
|
582
|
+
}
|
|
585
583
|
|
|
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
|
-
});
|
|
584
|
+
this._debug(`left <${id}> (${type}), pending runs ${postponedCount}, ${postponed.map((a) => a.content.id).join(',')}`);
|
|
593
585
|
|
|
594
|
-
|
|
586
|
+
if (postponedCount === detachedActivities.length) {
|
|
587
|
+
for (const api of this.getPostponed()) api.discard();
|
|
588
|
+
return;
|
|
595
589
|
}
|
|
596
590
|
|
|
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
|
-
};
|
|
591
|
+
if (isEnd && startActivities.length) {
|
|
592
|
+
const startSequences = this[elementsSymbol].startSequences;
|
|
593
|
+
for (const msg of postponed) {
|
|
594
|
+
const postponedId = msg.content.id;
|
|
595
|
+
const startSequence = startSequences[postponedId];
|
|
596
|
+
if (startSequence) {
|
|
597
|
+
if (startSequence.content.sequence.some(({id: sid}) => sid === id)) {
|
|
598
|
+
this._getChildApi(msg).discard();
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
612
602
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
proto._stopExecution = function stopExecution(message) {
|
|
606
|
+
if (this[stoppedSymbol]) return;
|
|
607
|
+
const postponedCount = this.postponedCount;
|
|
608
|
+
this._debug(`stop process execution (stop child executions ${postponedCount})`);
|
|
609
|
+
if (postponedCount) {
|
|
610
|
+
for (const api of this.getPostponed()) api.stop();
|
|
616
611
|
}
|
|
612
|
+
this._deactivate();
|
|
613
|
+
this[stoppedSymbol] = true;
|
|
614
|
+
return this.broker.publish(this._exchangeName, `execution.stopped.${this.executionId}`, {
|
|
615
|
+
...this[executeMessageSymbol].content,
|
|
616
|
+
...(message && message.content),
|
|
617
|
+
}, {type: 'stopped', persistent: false});
|
|
618
|
+
};
|
|
619
|
+
|
|
620
|
+
proto._onDiscard = function onDiscard() {
|
|
621
|
+
this._deactivate();
|
|
622
|
+
const running = this[elementsSymbol].postponed.splice(0);
|
|
623
|
+
this._debug(`discard process execution (discard child executions ${running.length})`);
|
|
624
|
+
|
|
625
|
+
for (const flow of this.getSequenceFlows()) flow.stop();
|
|
626
|
+
for (const msg of running) this._getChildApi(msg).discard();
|
|
627
|
+
|
|
628
|
+
this[activityQSymbol].purge();
|
|
629
|
+
return this._complete('discard');
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
proto._onApiMessage = function onApiMessage(routingKey, message) {
|
|
633
|
+
const executionId = this.executionId;
|
|
634
|
+
const broker = this.broker;
|
|
635
|
+
if (message.properties.delegate) {
|
|
636
|
+
const {correlationId} = message.properties || getUniqueId(executionId);
|
|
637
|
+
this._debug(`delegate api ${routingKey} message to children, with correlationId <${correlationId}>`);
|
|
638
|
+
|
|
639
|
+
let consumed = false;
|
|
640
|
+
broker.subscribeTmp('event', 'activity.consumed', (_, msg) => {
|
|
641
|
+
if (msg.properties.correlationId === correlationId) {
|
|
642
|
+
consumed = true;
|
|
643
|
+
this._debug(`delegated api message was consumed by ${msg.content ? msg.content.executionId : 'unknown'}`);
|
|
644
|
+
}
|
|
645
|
+
}, {consumerTag: `_ct-delegate-${correlationId}`, noAck: true});
|
|
617
646
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
647
|
+
for (const child of this[elementsSymbol].children) {
|
|
648
|
+
if (child.placeholder) continue;
|
|
649
|
+
child.broker.publish('api', routingKey, cloneContent(message.content), message.properties);
|
|
650
|
+
if (consumed) break;
|
|
651
|
+
}
|
|
621
652
|
|
|
622
|
-
|
|
623
|
-
return flows.find((f) => f.id === flowId);
|
|
653
|
+
return broker.cancel(`_ct-delegate-${correlationId}`);
|
|
624
654
|
}
|
|
625
655
|
|
|
626
|
-
|
|
627
|
-
|
|
656
|
+
if (this.id !== message.content.id) {
|
|
657
|
+
const child = this.getActivityById(message.content.id);
|
|
658
|
+
if (!child) return null;
|
|
659
|
+
return child.broker.publish('api', routingKey, message.content, message.properties);
|
|
628
660
|
}
|
|
629
661
|
|
|
630
|
-
|
|
631
|
-
return outboundMessageFlows.find((f) => f.id === flowId);
|
|
632
|
-
}
|
|
662
|
+
if (this.executionId !== message.content.executionId) return;
|
|
633
663
|
|
|
634
|
-
|
|
635
|
-
|
|
664
|
+
switch (message.properties.type) {
|
|
665
|
+
case 'discard':
|
|
666
|
+
return this.discard(message);
|
|
667
|
+
case 'stop':
|
|
668
|
+
this[activityQSymbol].queueMessage({routingKey: 'execution.stop'}, cloneContent(message.content), {persistent: false});
|
|
669
|
+
break;
|
|
636
670
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
proto._complete = function complete(completionType, content) {
|
|
674
|
+
this._deactivate();
|
|
675
|
+
this._debug(`process execution ${completionType}`);
|
|
676
|
+
this[completedSymbol] = true;
|
|
677
|
+
if (this.status !== 'terminated') this[statusSymbol] = completionType;
|
|
678
|
+
const broker = this.broker;
|
|
679
|
+
this[activityQSymbol].delete();
|
|
680
|
+
|
|
681
|
+
return broker.publish(this._exchangeName, `execution.${completionType}.${this.executionId}`, cloneContent(this[executeMessageSymbol].content, {
|
|
682
|
+
output: {...this.environment.output},
|
|
683
|
+
...content,
|
|
684
|
+
state: completionType,
|
|
685
|
+
}), {type: completionType, mandatory: completionType === 'error'});
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
proto._terminate = function terminate(message) {
|
|
689
|
+
this[statusSymbol] = 'terminated';
|
|
690
|
+
this._debug('terminating process execution');
|
|
691
|
+
|
|
692
|
+
const running = this[elementsSymbol].postponed.splice(0);
|
|
693
|
+
for (const flow of this.getSequenceFlows()) flow.stop();
|
|
694
|
+
|
|
695
|
+
for (const msg of running) {
|
|
696
|
+
const {id: postponedId, isSequenceFlow} = msg.content;
|
|
697
|
+
if (postponedId === message.content.id) continue;
|
|
698
|
+
if (isSequenceFlow) continue;
|
|
699
|
+
this._getChildApi(msg).stop();
|
|
700
|
+
msg.ack();
|
|
640
701
|
}
|
|
641
702
|
|
|
642
|
-
|
|
643
|
-
|
|
703
|
+
this[activityQSymbol].purge();
|
|
704
|
+
};
|
|
644
705
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
const api = ProcessApi(broker, message);
|
|
706
|
+
proto._getFlowById = function getFlowById(flowId) {
|
|
707
|
+
return this[elementsSymbol].flows.find((f) => f.id === flowId);
|
|
708
|
+
};
|
|
651
709
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
result.push(getApi(msg));
|
|
656
|
-
return result;
|
|
657
|
-
}, []);
|
|
658
|
-
};
|
|
710
|
+
proto._getAssociationById = function getAssociationById(associationId) {
|
|
711
|
+
return this[elementsSymbol].associations.find((a) => a.id === associationId);
|
|
712
|
+
};
|
|
659
713
|
|
|
660
|
-
|
|
661
|
-
|
|
714
|
+
proto._getMessageFlowById = function getMessageFlowById(flowId) {
|
|
715
|
+
return this[elementsSymbol].outboundMessageFlows.find((f) => f.id === flowId);
|
|
716
|
+
};
|
|
662
717
|
|
|
663
|
-
|
|
664
|
-
|
|
718
|
+
proto._getChildById = function getChildById(childId) {
|
|
719
|
+
return this.getActivityById(childId) || this._getFlowById(childId);
|
|
720
|
+
};
|
|
665
721
|
|
|
666
|
-
|
|
667
|
-
|
|
722
|
+
proto._getChildApi = function getChildApi(message) {
|
|
723
|
+
const content = message.content;
|
|
668
724
|
|
|
669
|
-
|
|
725
|
+
let child = this._getChildById(content.id);
|
|
726
|
+
if (child) return child.getApi(message);
|
|
670
727
|
|
|
671
|
-
|
|
672
|
-
if (api) return api;
|
|
728
|
+
if (!content.parent) return;
|
|
673
729
|
|
|
674
|
-
|
|
730
|
+
child = this._getChildById(content.parent.id);
|
|
731
|
+
if (child) return child.getApi(message);
|
|
675
732
|
|
|
676
|
-
|
|
677
|
-
api = getApiByChildId(content.parent.path[i].id);
|
|
678
|
-
if (api) return api;
|
|
679
|
-
}
|
|
733
|
+
if (!content.parent.path) return;
|
|
680
734
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
return child.getApi(message);
|
|
685
|
-
}
|
|
735
|
+
for (const pp of content.parent.path) {
|
|
736
|
+
child = this._getChildById(pp.id, message);
|
|
737
|
+
if (child) return child.getApi(message);
|
|
686
738
|
}
|
|
739
|
+
};
|
|
687
740
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
741
|
+
proto._onShookEnd = function onShookEnd(message) {
|
|
742
|
+
const routingKey = message.fields.routingKey;
|
|
743
|
+
if (routingKey !== 'activity.shake.end') return;
|
|
744
|
+
this[elementsSymbol].startSequences[message.content.id] = cloneMessage(message);
|
|
745
|
+
};
|
|
693
746
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
}
|
|
747
|
+
proto._debug = function debugMessage(logMessage) {
|
|
748
|
+
this[parentSymbol].logger.debug(`<${this.executionId} (${this.id})> ${logMessage}`);
|
|
749
|
+
};
|