bpmn-elements 17.3.0 → 18.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/Api.js +83 -0
- package/dist/Context.js +228 -22
- package/dist/Environment.js +111 -31
- package/dist/EventBroker.js +57 -1
- package/dist/Expressions.js +3 -4
- package/dist/MessageFormatter.js +29 -16
- package/dist/Timers.js +13 -9
- package/dist/Tracker.js +1 -0
- package/dist/activity/Activity.js +434 -233
- package/dist/activity/ActivityExecution.js +113 -40
- package/dist/activity/Dummy.js +6 -1
- package/dist/activity/Escalation.js +36 -24
- package/dist/activity/ExecutionScope.js +1 -1
- package/dist/activity/Message.js +36 -24
- package/dist/activity/Signal.js +36 -24
- package/dist/activity/outbound-evaluator.js +1 -1
- package/dist/condition.js +12 -6
- package/dist/constants.js +27 -0
- package/dist/definition/Definition.js +187 -64
- package/dist/definition/DefinitionExecution.js +198 -84
- package/dist/error/BpmnError.js +12 -1
- package/dist/error/Errors.js +50 -9
- package/dist/eventDefinitions/CancelEventDefinition.js +29 -11
- package/dist/eventDefinitions/CompensateEventDefinition.js +51 -31
- package/dist/eventDefinitions/ConditionalEventDefinition.js +21 -9
- package/dist/eventDefinitions/ErrorEventDefinition.js +46 -30
- package/dist/eventDefinitions/EscalationEventDefinition.js +44 -27
- package/dist/eventDefinitions/EventDefinitionExecution.js +30 -23
- package/dist/eventDefinitions/LinkEventDefinition.js +45 -120
- package/dist/eventDefinitions/MessageEventDefinition.js +44 -29
- package/dist/eventDefinitions/SignalEventDefinition.js +46 -31
- package/dist/eventDefinitions/TerminateEventDefinition.js +10 -1
- package/dist/eventDefinitions/TimerEventDefinition.js +57 -37
- package/dist/eventDefinitions/index.js +20 -21
- package/dist/events/BoundaryEvent.js +52 -40
- package/dist/events/EndEvent.js +22 -8
- package/dist/events/IntermediateCatchEvent.js +26 -8
- package/dist/events/IntermediateThrowEvent.js +24 -9
- package/dist/events/StartEvent.js +30 -14
- package/dist/events/index.js +10 -11
- package/dist/flows/Association.js +50 -7
- package/dist/flows/MessageFlow.js +49 -10
- package/dist/flows/SequenceFlow.js +93 -22
- package/dist/flows/index.js +6 -7
- package/dist/gateways/EventBasedGateway.js +29 -15
- package/dist/gateways/ExclusiveGateway.js +20 -5
- package/dist/gateways/InclusiveGateway.js +21 -5
- package/dist/gateways/ParallelGateway.js +253 -15
- package/dist/gateways/index.js +8 -9
- package/dist/getPropertyValue.js +1 -1
- package/dist/index.js +42 -43
- package/dist/io/BpmnIO.js +15 -1
- package/dist/io/EnvironmentDataObject.js +29 -1
- package/dist/io/EnvironmentDataStore.js +24 -1
- package/dist/io/EnvironmentDataStoreReference.js +24 -1
- package/dist/io/InputOutputSpecification.js +21 -11
- package/dist/io/Properties.js +28 -17
- package/dist/messageHelper.js +41 -4
- package/dist/process/Lane.js +15 -4
- package/dist/process/Process.js +176 -77
- package/dist/process/ProcessExecution.js +397 -178
- package/dist/shared.js +2 -0
- package/dist/tasks/CallActivity.js +19 -4
- package/dist/tasks/LoopCharacteristics.js +94 -9
- package/dist/tasks/ReceiveTask.js +36 -21
- package/dist/tasks/ScriptTask.js +22 -6
- package/dist/tasks/ServiceImplementation.js +7 -4
- package/dist/tasks/ServiceTask.js +19 -4
- package/dist/tasks/SignalTask.js +19 -4
- package/dist/tasks/StandardLoopCharacteristics.js +8 -4
- package/dist/tasks/SubProcess.js +44 -29
- package/dist/tasks/Task.js +19 -4
- package/dist/tasks/Transaction.js +8 -4
- package/dist/tasks/index.js +16 -18
- package/package.json +31 -13
- package/src/Api.js +70 -0
- package/src/Context.js +200 -19
- package/src/Environment.js +99 -30
- package/src/EventBroker.js +46 -1
- package/src/Expressions.js +2 -3
- package/src/MessageFormatter.js +24 -16
- package/src/Timers.js +12 -9
- package/src/Tracker.js +1 -0
- package/src/activity/Activity.js +372 -218
- package/src/activity/ActivityExecution.js +93 -42
- package/src/activity/Dummy.js +6 -1
- package/src/activity/Escalation.js +25 -18
- package/src/activity/ExecutionScope.js +1 -1
- package/src/activity/Message.js +25 -18
- package/src/activity/Signal.js +25 -18
- package/src/activity/outbound-evaluator.js +1 -1
- package/src/condition.js +11 -5
- package/src/constants.js +21 -0
- package/src/definition/Definition.js +165 -63
- package/src/definition/DefinitionExecution.js +164 -85
- package/src/error/BpmnError.js +11 -1
- package/src/error/Errors.js +44 -5
- package/src/eventDefinitions/CancelEventDefinition.js +27 -13
- package/src/eventDefinitions/CompensateEventDefinition.js +48 -32
- package/src/eventDefinitions/ConditionalEventDefinition.js +20 -10
- package/src/eventDefinitions/ErrorEventDefinition.js +44 -33
- package/src/eventDefinitions/EscalationEventDefinition.js +39 -26
- package/src/eventDefinitions/EventDefinitionExecution.js +30 -24
- package/src/eventDefinitions/LinkEventDefinition.js +34 -120
- package/src/eventDefinitions/MessageEventDefinition.js +42 -31
- package/src/eventDefinitions/SignalEventDefinition.js +43 -32
- package/src/eventDefinitions/TerminateEventDefinition.js +9 -1
- package/src/eventDefinitions/TimerEventDefinition.js +53 -35
- package/src/eventDefinitions/index.js +10 -23
- package/src/events/BoundaryEvent.js +50 -39
- package/src/events/EndEvent.js +19 -7
- package/src/events/IntermediateCatchEvent.js +24 -8
- package/src/events/IntermediateThrowEvent.js +24 -8
- package/src/events/StartEvent.js +25 -14
- package/src/events/index.js +5 -18
- package/src/flows/Association.js +43 -9
- package/src/flows/MessageFlow.js +41 -10
- package/src/flows/SequenceFlow.js +82 -19
- package/src/flows/index.js +3 -4
- package/src/gateways/EventBasedGateway.js +27 -15
- package/src/gateways/ExclusiveGateway.js +16 -3
- package/src/gateways/InclusiveGateway.js +16 -3
- package/src/gateways/ParallelGateway.js +301 -10
- package/src/gateways/index.js +4 -4
- package/src/getPropertyValue.js +1 -1
- package/src/index.js +19 -19
- package/src/io/BpmnIO.js +13 -1
- package/src/io/EnvironmentDataObject.js +26 -1
- package/src/io/EnvironmentDataStore.js +22 -1
- package/src/io/EnvironmentDataStoreReference.js +22 -1
- package/src/io/InputOutputSpecification.js +17 -8
- package/src/io/Properties.js +23 -13
- package/src/messageHelper.js +36 -4
- package/src/process/Lane.js +14 -4
- package/src/process/Process.js +157 -74
- package/src/process/ProcessExecution.js +363 -176
- package/src/shared.js +1 -0
- package/src/tasks/CallActivity.js +16 -2
- package/src/tasks/LoopCharacteristics.js +77 -11
- package/src/tasks/ReceiveTask.js +33 -22
- package/src/tasks/ScriptTask.js +17 -3
- package/src/tasks/ServiceImplementation.js +6 -3
- package/src/tasks/ServiceTask.js +16 -2
- package/src/tasks/SignalTask.js +16 -2
- package/src/tasks/StandardLoopCharacteristics.js +7 -3
- package/src/tasks/SubProcess.js +37 -23
- package/src/tasks/Task.js +16 -2
- package/src/tasks/Transaction.js +7 -3
- package/src/tasks/index.js +8 -9
- package/types/bundle-errors.d.ts +1 -0
- package/types/bundle.d.ts +97 -0
- package/types/index.d.ts +2619 -84
- package/types/interfaces.d.ts +638 -0
- package/types/types.d.ts +0 -765
package/src/activity/Activity.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ActivityExecution from './ActivityExecution.js';
|
|
1
|
+
import { ActivityExecution } from './ActivityExecution.js';
|
|
2
2
|
import { getUniqueId } from '../shared.js';
|
|
3
3
|
import { ActivityApi } from '../Api.js';
|
|
4
4
|
import { ActivityBroker } from '../EventBroker.js';
|
|
@@ -6,39 +6,55 @@ import { Formatter } from '../MessageFormatter.js';
|
|
|
6
6
|
import { cloneContent, cloneParent, cloneMessage } from '../messageHelper.js';
|
|
7
7
|
import { makeErrorFromMessage, ActivityError } from '../error/Errors.js';
|
|
8
8
|
import { OutboundEvaluator, formatFlowAction } from './outbound-evaluator.js';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
9
|
+
import {
|
|
10
|
+
K_ACTIVATED,
|
|
11
|
+
K_CONSUMING,
|
|
12
|
+
K_COUNTERS,
|
|
13
|
+
K_EXECUTE_MESSAGE,
|
|
14
|
+
K_EXTENSIONS,
|
|
15
|
+
K_MESSAGE_HANDLERS,
|
|
16
|
+
K_STATE_MESSAGE,
|
|
17
|
+
} from '../constants.js';
|
|
18
|
+
|
|
19
|
+
const K_ACTIVITY_DEF = Symbol.for('activityDefinition');
|
|
20
|
+
const K_CONSUMING_RUN_Q = Symbol.for('run queue consumer');
|
|
21
|
+
const K_EVENT_DEFINITIONS = Symbol.for('eventDefinitions');
|
|
22
|
+
const K_EXEC = Symbol.for('exec');
|
|
23
|
+
const K_FLAGS = Symbol.for('flags');
|
|
24
|
+
const K_FLOWS = Symbol.for('flows');
|
|
25
|
+
const K_FORMATTER = Symbol.for('formatter');
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Activity wraps any element (task, event, gateway) and orchestrates its lifecycle through the broker.
|
|
29
|
+
* @param {import('#types').IActivityBehaviour} Behaviour Element-specific behaviour constructor invoked per execution
|
|
30
|
+
* @param {import('moddle-context-serializer').Activity} activityDef Parsed BPMN element definition
|
|
31
|
+
* @param {import('#types').ContextInstance} context Per-execution registry and factory
|
|
32
|
+
*/
|
|
33
|
+
export function Activity(Behaviour, activityDef, context) {
|
|
28
34
|
const { id, type = 'activity', name, behaviour = {} } = activityDef;
|
|
29
35
|
const { attachedTo: attachedToRef, eventDefinitions } = behaviour;
|
|
30
36
|
|
|
31
|
-
this[
|
|
37
|
+
this[K_ACTIVITY_DEF] = activityDef;
|
|
32
38
|
this.id = id;
|
|
33
39
|
this.type = type;
|
|
34
40
|
this.name = name;
|
|
35
|
-
|
|
41
|
+
/** @type {import('moddle-context-serializer').ActivityBehaviour} */
|
|
42
|
+
this.behaviour = {
|
|
43
|
+
...behaviour,
|
|
44
|
+
eventDefinitions,
|
|
45
|
+
...(activityDef.linkNames && { linkNames: activityDef.linkNames, linkBehaviour: activityDef.linkBehaviour }),
|
|
46
|
+
};
|
|
36
47
|
this.Behaviour = Behaviour;
|
|
48
|
+
/** @type {import('moddle-context-serializer').Parent} */
|
|
37
49
|
this.parent = activityDef.parent ? cloneParent(activityDef.parent) : {};
|
|
50
|
+
/** @type {import('#types').ILogger} */
|
|
38
51
|
this.logger = context.environment.Logger(type.toLowerCase());
|
|
39
52
|
this.environment = context.environment;
|
|
40
53
|
this.context = context;
|
|
41
|
-
|
|
54
|
+
/** @type {import('#types').ActivityStatus | undefined} */
|
|
55
|
+
this.status = undefined;
|
|
56
|
+
|
|
57
|
+
this[K_COUNTERS] = {
|
|
42
58
|
taken: 0,
|
|
43
59
|
discarded: 0,
|
|
44
60
|
};
|
|
@@ -60,159 +76,175 @@ function Activity(Behaviour, activityDef, context) {
|
|
|
60
76
|
|
|
61
77
|
const inboundSequenceFlows = context.getInboundSequenceFlows(id);
|
|
62
78
|
const inboundAssociations = context.getInboundAssociations(id);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
inboundTriggers = [attachedToActivity];
|
|
66
|
-
} else if (isForCompensation) {
|
|
67
|
-
inboundTriggers = inboundAssociations.slice();
|
|
68
|
-
} else {
|
|
69
|
-
inboundTriggers = inboundSequenceFlows.slice();
|
|
70
|
-
}
|
|
79
|
+
const hasInboundTrigger = attachedToActivity ? true : isForCompensation ? !!inboundAssociations.length : !!inboundSequenceFlows.length;
|
|
80
|
+
|
|
71
81
|
const outboundSequenceFlows = context.getOutboundSequenceFlows(id);
|
|
72
82
|
|
|
73
|
-
const
|
|
83
|
+
const inboundSourceIds = new Set(inboundSequenceFlows.map(({ sourceId }) => sourceId));
|
|
84
|
+
const isParallelJoin = activityDef.isParallelGateway && inboundSourceIds.size > 1;
|
|
74
85
|
|
|
75
|
-
this[
|
|
86
|
+
this[K_FLOWS] = {
|
|
76
87
|
inboundSequenceFlows,
|
|
77
88
|
inboundAssociations,
|
|
78
|
-
inboundTriggers,
|
|
89
|
+
inboundTriggers: undefined,
|
|
79
90
|
outboundSequenceFlows,
|
|
80
91
|
outboundEvaluator: new OutboundEvaluator(this, outboundSequenceFlows),
|
|
81
|
-
...(isParallelJoin && {
|
|
82
|
-
inboundJoinFlows: new Set(),
|
|
83
|
-
inboundSourceIds: new Set(inboundSequenceFlows.map(({ sourceId }) => sourceId)),
|
|
84
|
-
}),
|
|
85
92
|
};
|
|
86
93
|
|
|
87
|
-
this[
|
|
94
|
+
this[K_FLAGS] = {
|
|
88
95
|
isEnd: !outboundSequenceFlows.length,
|
|
89
|
-
isStart: !
|
|
96
|
+
isStart: !hasInboundTrigger && !behaviour.triggeredByEvent && !activityDef.isCatching,
|
|
90
97
|
isSubProcess: activityDef.isSubProcess,
|
|
91
98
|
isMultiInstance: !!behaviour.loopCharacteristics,
|
|
92
99
|
isForCompensation,
|
|
93
100
|
attachedTo,
|
|
94
101
|
isTransaction: activityDef.isTransaction,
|
|
95
102
|
isParallelJoin,
|
|
103
|
+
isParallelGateway: activityDef.isParallelGateway,
|
|
104
|
+
isStartEvent: !!activityDef.isStartEvent,
|
|
96
105
|
isThrowing: activityDef.isThrowing,
|
|
106
|
+
linkNames: activityDef.linkNames,
|
|
107
|
+
linkBehaviour: activityDef.linkBehaviour,
|
|
108
|
+
isCatching: activityDef.isCatching,
|
|
97
109
|
lane: activityDef.lane?.id,
|
|
98
110
|
};
|
|
99
|
-
this[
|
|
111
|
+
this[K_EXEC] = new Map();
|
|
100
112
|
|
|
101
|
-
this[
|
|
102
|
-
onInbound:
|
|
113
|
+
this[K_MESSAGE_HANDLERS] = {
|
|
114
|
+
onInbound: this._onInbound.bind(this),
|
|
103
115
|
onRunMessage: this._onRunMessage.bind(this),
|
|
104
116
|
onApiMessage: this._onApiMessage.bind(this),
|
|
105
117
|
onExecutionMessage: this._onExecutionMessage.bind(this),
|
|
106
118
|
};
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
this[
|
|
110
|
-
this[
|
|
111
|
-
this[
|
|
120
|
+
/** @type {import('#types').EventDefinition[] | undefined} */
|
|
121
|
+
this[K_EVENT_DEFINITIONS] = eventDefinitions?.map((ed, idx) => new ed.Behaviour(this, ed, context, idx));
|
|
122
|
+
this[K_EXTENSIONS] = context.loadExtensions(this);
|
|
123
|
+
this[K_CONSUMING] = false;
|
|
124
|
+
this[K_CONSUMING_RUN_Q] = undefined;
|
|
112
125
|
}
|
|
113
126
|
|
|
114
127
|
Object.defineProperties(Activity.prototype, {
|
|
115
128
|
counters: {
|
|
116
129
|
get() {
|
|
117
|
-
return { ...this[
|
|
130
|
+
return { ...this[K_COUNTERS] };
|
|
118
131
|
},
|
|
119
132
|
},
|
|
120
133
|
execution: {
|
|
121
134
|
get() {
|
|
122
|
-
return this[
|
|
135
|
+
return this[K_EXEC].get('execution');
|
|
123
136
|
},
|
|
124
137
|
},
|
|
125
138
|
executionId: {
|
|
126
139
|
get() {
|
|
127
|
-
return this[
|
|
140
|
+
return this[K_EXEC].get('executionId');
|
|
128
141
|
},
|
|
129
142
|
},
|
|
130
143
|
extensions: {
|
|
131
144
|
get() {
|
|
132
|
-
return this[
|
|
145
|
+
return this[K_EXTENSIONS];
|
|
133
146
|
},
|
|
134
147
|
},
|
|
135
148
|
bpmnIo: {
|
|
136
149
|
get() {
|
|
137
|
-
const extensions = this[
|
|
150
|
+
const extensions = this[K_EXTENSIONS];
|
|
138
151
|
return extensions?.extensions.find((e) => e.type === 'bpmnio');
|
|
139
152
|
},
|
|
140
153
|
},
|
|
141
154
|
formatter: {
|
|
142
155
|
get() {
|
|
143
|
-
let formatter = this[
|
|
156
|
+
let formatter = this[K_FORMATTER];
|
|
144
157
|
if (formatter) return formatter;
|
|
145
|
-
|
|
146
|
-
formatter = this[kFormatter] = new Formatter(this);
|
|
158
|
+
formatter = this[K_FORMATTER] = new Formatter(this);
|
|
147
159
|
return formatter;
|
|
148
160
|
},
|
|
149
161
|
},
|
|
150
162
|
isRunning: {
|
|
151
163
|
get() {
|
|
152
|
-
if (!this[
|
|
164
|
+
if (!this[K_CONSUMING]) return false;
|
|
153
165
|
return !!this.status;
|
|
154
166
|
},
|
|
155
167
|
},
|
|
156
168
|
outbound: {
|
|
157
169
|
get() {
|
|
158
|
-
return this[
|
|
170
|
+
return this[K_FLOWS].outboundSequenceFlows;
|
|
159
171
|
},
|
|
160
172
|
},
|
|
161
173
|
inbound: {
|
|
162
174
|
get() {
|
|
163
|
-
return this[
|
|
175
|
+
return this[K_FLOWS].inboundSequenceFlows;
|
|
164
176
|
},
|
|
165
177
|
},
|
|
166
178
|
isEnd: {
|
|
167
179
|
get() {
|
|
168
|
-
return this[
|
|
180
|
+
return this[K_FLAGS].isEnd;
|
|
169
181
|
},
|
|
170
182
|
},
|
|
171
183
|
isStart: {
|
|
172
184
|
get() {
|
|
173
|
-
return this[
|
|
185
|
+
return this[K_FLAGS].isStart;
|
|
174
186
|
},
|
|
175
187
|
},
|
|
176
188
|
isSubProcess: {
|
|
177
189
|
get() {
|
|
178
|
-
return this[
|
|
190
|
+
return this[K_FLAGS].isSubProcess;
|
|
179
191
|
},
|
|
180
192
|
},
|
|
181
193
|
isTransaction: {
|
|
182
194
|
get() {
|
|
183
|
-
return this[
|
|
195
|
+
return this[K_FLAGS].isTransaction;
|
|
184
196
|
},
|
|
185
197
|
},
|
|
186
198
|
isMultiInstance: {
|
|
187
199
|
get() {
|
|
188
|
-
return this[
|
|
200
|
+
return this[K_FLAGS].isMultiInstance;
|
|
189
201
|
},
|
|
190
202
|
},
|
|
191
203
|
isThrowing: {
|
|
192
204
|
get() {
|
|
193
|
-
return this[
|
|
205
|
+
return this[K_FLAGS].isThrowing;
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
isCatching: {
|
|
209
|
+
get() {
|
|
210
|
+
return this[K_FLAGS].isCatching;
|
|
194
211
|
},
|
|
195
212
|
},
|
|
196
213
|
isForCompensation: {
|
|
197
214
|
get() {
|
|
198
|
-
return this[
|
|
215
|
+
return this[K_FLAGS].isForCompensation;
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
isParallelJoin: {
|
|
219
|
+
get() {
|
|
220
|
+
return this[K_FLAGS].isParallelJoin;
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
isParallelGateway: {
|
|
224
|
+
get() {
|
|
225
|
+
return this[K_FLAGS].isParallelGateway;
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
isStartEvent: {
|
|
229
|
+
get() {
|
|
230
|
+
return this[K_FLAGS].isStartEvent;
|
|
199
231
|
},
|
|
200
232
|
},
|
|
201
233
|
triggeredByEvent: {
|
|
202
234
|
get() {
|
|
203
|
-
return this[
|
|
235
|
+
return this[K_ACTIVITY_DEF].triggeredByEvent;
|
|
204
236
|
},
|
|
205
237
|
},
|
|
206
238
|
attachedTo: {
|
|
207
239
|
get() {
|
|
208
|
-
const attachedToId = this[
|
|
240
|
+
const attachedToId = this[K_FLAGS].attachedTo;
|
|
209
241
|
if (!attachedToId) return null;
|
|
210
242
|
return this.getActivityById(attachedToId);
|
|
211
243
|
},
|
|
212
244
|
},
|
|
213
245
|
lane: {
|
|
214
246
|
get() {
|
|
215
|
-
const laneId = this[
|
|
247
|
+
const laneId = this[K_FLAGS].lane;
|
|
216
248
|
if (!laneId) return undefined;
|
|
217
249
|
const parent = this.parentElement;
|
|
218
250
|
return parent.getLaneById && parent.getLaneById(laneId);
|
|
@@ -220,7 +252,7 @@ Object.defineProperties(Activity.prototype, {
|
|
|
220
252
|
},
|
|
221
253
|
eventDefinitions: {
|
|
222
254
|
get() {
|
|
223
|
-
return this[
|
|
255
|
+
return this[K_EVENT_DEFINITIONS];
|
|
224
256
|
},
|
|
225
257
|
},
|
|
226
258
|
parentElement: {
|
|
@@ -228,36 +260,85 @@ Object.defineProperties(Activity.prototype, {
|
|
|
228
260
|
return this.context.getActivityParentById(this.id);
|
|
229
261
|
},
|
|
230
262
|
},
|
|
263
|
+
initialized: {
|
|
264
|
+
get() {
|
|
265
|
+
return !!this[K_EXEC]?.get('initExecutionId');
|
|
266
|
+
},
|
|
267
|
+
},
|
|
231
268
|
});
|
|
232
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Subscribe to inbound flows and start consuming the inbound queue.
|
|
272
|
+
* @returns {void}
|
|
273
|
+
*/
|
|
233
274
|
Activity.prototype.activate = function activate() {
|
|
234
|
-
if (this[
|
|
235
|
-
this[
|
|
275
|
+
if (this[K_ACTIVATED]) return;
|
|
276
|
+
this[K_ACTIVATED] = true;
|
|
236
277
|
return this.addInboundListeners() && this._consumeInbound();
|
|
237
278
|
};
|
|
238
279
|
|
|
280
|
+
/** @internal */
|
|
281
|
+
Activity.prototype._getInboundTriggers = function _getInboundTriggers() {
|
|
282
|
+
const flows = this[K_FLOWS];
|
|
283
|
+
if (flows.inboundTriggers) return flows.inboundTriggers;
|
|
284
|
+
|
|
285
|
+
const flags = this[K_FLAGS];
|
|
286
|
+
let triggers;
|
|
287
|
+
if (flags.attachedTo) {
|
|
288
|
+
triggers = [this.context.getActivityById(flags.attachedTo)];
|
|
289
|
+
} else if (flags.isForCompensation) {
|
|
290
|
+
triggers = flows.inboundAssociations.slice();
|
|
291
|
+
} else {
|
|
292
|
+
triggers = flows.inboundSequenceFlows.slice();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const { isCatching, linkNames, linkBehaviour } = flags;
|
|
296
|
+
if (isCatching && linkNames?.length) {
|
|
297
|
+
const known = new Set(triggers.map((t) => t.id));
|
|
298
|
+
for (const source of this.context.getActivitiesByEventDefinitionBehaviour(linkBehaviour, linkNames)) {
|
|
299
|
+
if (source.id === this.id || !source.isThrowing || known.has(source.id)) continue;
|
|
300
|
+
triggers.push(source);
|
|
301
|
+
known.add(source.id);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return (flows.inboundTriggers = triggers);
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Cancel inbound subscriptions and any pending run/format consumers.
|
|
310
|
+
*/
|
|
239
311
|
Activity.prototype.deactivate = function deactivate() {
|
|
240
|
-
this[
|
|
312
|
+
this[K_ACTIVATED] = false;
|
|
241
313
|
const broker = this.broker;
|
|
242
314
|
this.removeInboundListeners();
|
|
243
315
|
broker.cancel('_run-on-inbound');
|
|
244
316
|
broker.cancel('_format-consumer');
|
|
245
317
|
};
|
|
246
318
|
|
|
319
|
+
/**
|
|
320
|
+
* Initialise activity executionId and emit init event without starting the run.
|
|
321
|
+
* @param {Record<string, any>} [initContent] Optional content merged into the init message
|
|
322
|
+
*/
|
|
247
323
|
Activity.prototype.init = function init(initContent) {
|
|
248
324
|
const id = this.id;
|
|
249
|
-
const exec = this[
|
|
325
|
+
const exec = this[K_EXEC];
|
|
250
326
|
const executionId = exec.has('initExecutionId') ? exec.get('initExecutionId') : getUniqueId(id);
|
|
251
327
|
exec.set('initExecutionId', executionId);
|
|
252
328
|
this.logger.debug(`<${id}> initialized with executionId <${executionId}>`);
|
|
253
329
|
this._publishEvent('init', this._createMessage({ ...initContent, executionId }));
|
|
254
330
|
};
|
|
255
331
|
|
|
332
|
+
/**
|
|
333
|
+
* Start running the activity by publishing run.enter and run.start.
|
|
334
|
+
* @param {Record<string, any>} [runContent] Optional content merged into the run message
|
|
335
|
+
* @throws {Error} if the activity is already running
|
|
336
|
+
*/
|
|
256
337
|
Activity.prototype.run = function run(runContent) {
|
|
257
338
|
const id = this.id;
|
|
258
339
|
if (this.isRunning) throw new Error(`activity <${id}> is already running`);
|
|
259
340
|
|
|
260
|
-
const exec = this[
|
|
341
|
+
const exec = this[K_EXEC];
|
|
261
342
|
const executionId = exec.get('initExecutionId') || getUniqueId(id);
|
|
262
343
|
exec.set('executionId', executionId);
|
|
263
344
|
exec.delete('initExecutionId');
|
|
@@ -270,13 +351,18 @@ Activity.prototype.run = function run(runContent) {
|
|
|
270
351
|
broker.publish('run', 'run.enter', content);
|
|
271
352
|
broker.publish('run', 'run.start', cloneContent(content));
|
|
272
353
|
|
|
273
|
-
this[
|
|
354
|
+
this[K_CONSUMING] = true;
|
|
274
355
|
this._consumeRunQ();
|
|
275
356
|
};
|
|
276
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Snapshot activity state for recover.
|
|
360
|
+
* Returns undefined when nothing is running and `disableTrackState` is set.
|
|
361
|
+
* @returns {import('#types').ActivityState}
|
|
362
|
+
*/
|
|
277
363
|
Activity.prototype.getState = function getState() {
|
|
278
364
|
const status = this.status;
|
|
279
|
-
const exec = this[
|
|
365
|
+
const exec = this[K_EXEC];
|
|
280
366
|
const execution = exec.get('execution');
|
|
281
367
|
const executionId = exec.get('executionId');
|
|
282
368
|
const brokerState = this.broker.getState(true);
|
|
@@ -294,16 +380,22 @@ Activity.prototype.getState = function getState() {
|
|
|
294
380
|
};
|
|
295
381
|
};
|
|
296
382
|
|
|
383
|
+
/**
|
|
384
|
+
* Restore activity state captured by getState. Cannot be called while running.
|
|
385
|
+
* @param {import('#types').ActivityState} [state]
|
|
386
|
+
* @returns {this} this when state was applied
|
|
387
|
+
* @throws {Error} when activity is currently running
|
|
388
|
+
*/
|
|
297
389
|
Activity.prototype.recover = function recover(state) {
|
|
298
390
|
if (this.isRunning) throw new Error(`cannot recover running activity <${this.id}>`);
|
|
299
|
-
if (!state) return;
|
|
391
|
+
if (!state) return this;
|
|
300
392
|
|
|
301
393
|
this.stopped = state.stopped;
|
|
302
394
|
this.status = state.status;
|
|
303
|
-
const exec = this[
|
|
395
|
+
const exec = this[K_EXEC];
|
|
304
396
|
exec.set('executionId', state.executionId);
|
|
305
397
|
|
|
306
|
-
this[
|
|
398
|
+
this[K_COUNTERS] = { ...this[K_COUNTERS], ...state.counters };
|
|
307
399
|
|
|
308
400
|
if (state.execution) {
|
|
309
401
|
exec.set('execution', new ActivityExecution(this, this.context).recover(state.execution));
|
|
@@ -314,8 +406,12 @@ Activity.prototype.recover = function recover(state) {
|
|
|
314
406
|
return this;
|
|
315
407
|
};
|
|
316
408
|
|
|
409
|
+
/**
|
|
410
|
+
* Resume after recover. If no run has been started, falls back to activate.
|
|
411
|
+
* @throws {Error} when called on a running activity
|
|
412
|
+
*/
|
|
317
413
|
Activity.prototype.resume = function resume() {
|
|
318
|
-
if (this[
|
|
414
|
+
if (this[K_CONSUMING]) {
|
|
319
415
|
throw new Error(`cannot resume running activity <${this.id}>`);
|
|
320
416
|
}
|
|
321
417
|
if (!this.status) return this.activate();
|
|
@@ -327,25 +423,34 @@ Activity.prototype.resume = function resume() {
|
|
|
327
423
|
const content = this._createMessage();
|
|
328
424
|
this.broker.publish('run', 'run.resume', content, { persistent: false });
|
|
329
425
|
|
|
330
|
-
this[
|
|
426
|
+
this[K_CONSUMING] = true;
|
|
331
427
|
this._consumeRunQ();
|
|
332
428
|
};
|
|
333
429
|
|
|
430
|
+
/**
|
|
431
|
+
* Discard the activity. Stops execution if running; the activity leaves without taking any outbound flow.
|
|
432
|
+
* @param {Record<string, any>} [discardContent] Optional content propagated with the discard
|
|
433
|
+
* @returns {void}
|
|
434
|
+
*/
|
|
334
435
|
Activity.prototype.discard = function discard(discardContent) {
|
|
335
436
|
if (!this.status) return this._runDiscard(discardContent);
|
|
336
|
-
const execution = this[
|
|
437
|
+
const execution = this[K_EXEC].get('execution');
|
|
337
438
|
if (execution && !execution.completed) return execution.discard();
|
|
338
439
|
|
|
339
440
|
this._deactivateRunConsumers();
|
|
340
441
|
const broker = this.broker;
|
|
341
442
|
broker.getQueue('run-q').purge();
|
|
342
|
-
broker.publish('run', 'run.discard', cloneContent(this[
|
|
343
|
-
this[
|
|
443
|
+
broker.publish('run', 'run.discard', cloneContent(this[K_STATE_MESSAGE].content));
|
|
444
|
+
this[K_CONSUMING] = true;
|
|
344
445
|
this._consumeRunQ();
|
|
345
446
|
};
|
|
346
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Subscribe to inbound triggers (sequence flows, attached activity, or compensation associations).
|
|
450
|
+
* @returns {number} count of subscribed triggers
|
|
451
|
+
*/
|
|
347
452
|
Activity.prototype.addInboundListeners = function addInboundListeners() {
|
|
348
|
-
const triggers = this
|
|
453
|
+
const triggers = this._getInboundTriggers();
|
|
349
454
|
if (triggers.length) {
|
|
350
455
|
const onInboundEvent = this._onInboundEvent.bind(this);
|
|
351
456
|
const triggerConsumerTag = `_inbound-${this.id}`;
|
|
@@ -362,21 +467,33 @@ Activity.prototype.addInboundListeners = function addInboundListeners() {
|
|
|
362
467
|
return triggers.length;
|
|
363
468
|
};
|
|
364
469
|
|
|
470
|
+
/**
|
|
471
|
+
* Cancel inbound trigger subscriptions added by addInboundListeners.
|
|
472
|
+
*/
|
|
365
473
|
Activity.prototype.removeInboundListeners = function removeInboundListeners() {
|
|
474
|
+
const triggers = this[K_FLOWS].inboundTriggers;
|
|
475
|
+
if (!triggers) return;
|
|
366
476
|
const triggerConsumerTag = `_inbound-${this.id}`;
|
|
367
|
-
for (const trigger of
|
|
477
|
+
for (const trigger of triggers) {
|
|
368
478
|
trigger.broker.cancel(triggerConsumerTag);
|
|
369
479
|
}
|
|
370
480
|
};
|
|
371
481
|
|
|
482
|
+
/**
|
|
483
|
+
* Stop the activity. If not currently running, just cancels the inbound consumer.
|
|
484
|
+
*/
|
|
372
485
|
Activity.prototype.stop = function stop() {
|
|
373
|
-
if (!this[
|
|
374
|
-
return this.getApi(this[
|
|
486
|
+
if (!this[K_CONSUMING]) return this.broker.cancel('_run-on-inbound');
|
|
487
|
+
return this.getApi(this[K_STATE_MESSAGE]).stop();
|
|
375
488
|
};
|
|
376
489
|
|
|
490
|
+
/**
|
|
491
|
+
* Advance one run-step when the environment runs in step mode. No-op otherwise.
|
|
492
|
+
*/
|
|
377
493
|
Activity.prototype.next = function next() {
|
|
378
494
|
if (!this.environment.settings.step) return;
|
|
379
|
-
|
|
495
|
+
/** @type {import('#types').ElementBrokerMessage} */
|
|
496
|
+
const stateMessage = this[K_STATE_MESSAGE];
|
|
380
497
|
if (!stateMessage) return;
|
|
381
498
|
if (this.status === 'executing') return false;
|
|
382
499
|
if (this.status === 'formatting') return false;
|
|
@@ -385,26 +502,46 @@ Activity.prototype.next = function next() {
|
|
|
385
502
|
return current;
|
|
386
503
|
};
|
|
387
504
|
|
|
505
|
+
/**
|
|
506
|
+
* Walk outbound flows to discover the activity graph from this point.
|
|
507
|
+
*/
|
|
388
508
|
Activity.prototype.shake = function shake() {
|
|
389
509
|
this._shakeOutbound({ content: this._createMessage() });
|
|
390
510
|
};
|
|
391
511
|
|
|
512
|
+
/**
|
|
513
|
+
* Evaluate outbound sequence flows for the given source message.
|
|
514
|
+
* @param {import('#types').ElementBrokerMessage} fromMessage Source run message
|
|
515
|
+
* @param {boolean} discardRestAtTake When true, take only the first matching flow and discard the rest
|
|
516
|
+
* @param {(err: Error, evaluationResult: any) => void} callback
|
|
517
|
+
* @returns {void}
|
|
518
|
+
*/
|
|
392
519
|
Activity.prototype.evaluateOutbound = function evaluateOutbound(fromMessage, discardRestAtTake, callback) {
|
|
393
|
-
return this[
|
|
520
|
+
return this[K_FLOWS].outboundEvaluator.evaluate(fromMessage, discardRestAtTake, callback);
|
|
394
521
|
};
|
|
395
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Resolve an Api wrapper for the activity, preferring the running execution if any.
|
|
525
|
+
* @param {import('#types').ElementBrokerMessage} [message]
|
|
526
|
+
* @returns {import('#types').IApi<import('./Activity.js').Activity>}
|
|
527
|
+
*/
|
|
396
528
|
Activity.prototype.getApi = function getApi(message) {
|
|
397
|
-
const execution = this[
|
|
529
|
+
const execution = this[K_EXEC].get('execution');
|
|
398
530
|
if (execution && !execution.completed) return execution.getApi(message);
|
|
399
|
-
return ActivityApi(this.broker, message || this[
|
|
531
|
+
return ActivityApi(this.broker, message || this[K_STATE_MESSAGE]);
|
|
400
532
|
};
|
|
401
533
|
|
|
534
|
+
/**
|
|
535
|
+
* Look up another activity in the same context.
|
|
536
|
+
* @param {string} elementId
|
|
537
|
+
*/
|
|
402
538
|
Activity.prototype.getActivityById = function getActivityById(elementId) {
|
|
403
539
|
return this.context.getActivityById(elementId);
|
|
404
540
|
};
|
|
405
541
|
|
|
542
|
+
/** @internal */
|
|
406
543
|
Activity.prototype._runDiscard = function runDiscard(discardContent) {
|
|
407
|
-
const exec = this[
|
|
544
|
+
const exec = this[K_EXEC];
|
|
408
545
|
const executionId = exec.get('initExecutionId') || getUniqueId(this.id);
|
|
409
546
|
exec.set('executionId', executionId);
|
|
410
547
|
exec.delete('initExecutionId');
|
|
@@ -414,15 +551,16 @@ Activity.prototype._runDiscard = function runDiscard(discardContent) {
|
|
|
414
551
|
const content = this._createMessage({ ...discardContent, executionId });
|
|
415
552
|
this.broker.publish('run', 'run.discard', content);
|
|
416
553
|
|
|
417
|
-
this[
|
|
554
|
+
this[K_CONSUMING] = true;
|
|
418
555
|
this._consumeRunQ();
|
|
419
556
|
};
|
|
420
557
|
|
|
558
|
+
/** @internal */
|
|
421
559
|
Activity.prototype._discardRun = function discardRun() {
|
|
422
560
|
const status = this.status;
|
|
423
561
|
if (!status) return;
|
|
424
562
|
|
|
425
|
-
const execution = this[
|
|
563
|
+
const execution = this[K_EXEC].get('execution');
|
|
426
564
|
if (execution && !execution.completed) return;
|
|
427
565
|
|
|
428
566
|
let discardRoutingKey = 'run.discard';
|
|
@@ -440,47 +578,82 @@ Activity.prototype._discardRun = function discardRun() {
|
|
|
440
578
|
|
|
441
579
|
this._deactivateRunConsumers();
|
|
442
580
|
|
|
443
|
-
const stateMessage = this[
|
|
581
|
+
const stateMessage = this[K_STATE_MESSAGE];
|
|
444
582
|
if (this.extensions) this.extensions.deactivate(cloneMessage(stateMessage));
|
|
445
583
|
|
|
446
584
|
const broker = this.broker;
|
|
447
585
|
broker.getQueue('run-q').purge();
|
|
448
586
|
|
|
449
587
|
broker.publish('run', discardRoutingKey, cloneContent(stateMessage.content), { correlationId: stateMessage.properties.correlationId });
|
|
450
|
-
this[
|
|
588
|
+
this[K_CONSUMING] = true;
|
|
451
589
|
this._consumeRunQ();
|
|
452
590
|
};
|
|
453
591
|
|
|
592
|
+
/** @internal */
|
|
593
|
+
Activity.prototype._onShakeMessage = function _onShakeMessage(sourceMessage) {
|
|
594
|
+
if (this[K_FLAGS].isParallelGateway) {
|
|
595
|
+
const message = cloneMessage(sourceMessage, { join: this.id });
|
|
596
|
+
message.content.sequence.push({ id: this.id, type: this.type });
|
|
597
|
+
return this.broker.publish('event', 'activity.shake.join', message.content, {
|
|
598
|
+
persistent: false,
|
|
599
|
+
type: 'shake',
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
this._shakeOutbound(sourceMessage);
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
/** @internal */
|
|
454
607
|
Activity.prototype._shakeOutbound = function shakeOutbound(sourceMessage) {
|
|
455
608
|
const message = cloneMessage(sourceMessage);
|
|
456
|
-
message.content.sequence = message.content.sequence || [];
|
|
457
|
-
|
|
609
|
+
const sequence = (message.content.sequence = message.content.sequence || []);
|
|
610
|
+
const count = 1;
|
|
611
|
+
const looped = sequence?.find((f) => f.id === this.id);
|
|
612
|
+
|
|
613
|
+
sequence.push({ id: this.id, type: this.type, count: looped ? looped.count + 1 : count });
|
|
458
614
|
|
|
459
|
-
const broker = this.broker;
|
|
460
615
|
this.broker.publish('api', 'activity.shake.start', message.content, { persistent: false, type: 'shake' });
|
|
461
616
|
|
|
462
|
-
|
|
463
|
-
|
|
617
|
+
const flags = this[K_FLAGS];
|
|
618
|
+
if (flags.isThrowing && flags.linkNames?.length) {
|
|
619
|
+
for (const target of this.context.getActivitiesByEventDefinitionBehaviour(flags.linkBehaviour, flags.linkNames)) {
|
|
620
|
+
if (target.id === this.id || !target.isCatching) continue;
|
|
621
|
+
const linkedContent = cloneContent(message.content, { sourceId: this.id, targetId: target.id, isLinked: true });
|
|
622
|
+
linkedContent.sequence = linkedContent.sequence.concat({ id: target.id, type: target.type });
|
|
623
|
+
target.broker.publish('event', 'activity.shake.linked', linkedContent, { persistent: false, type: 'shake' });
|
|
624
|
+
for (const flow of target.outbound) flow.shake({ content: cloneContent(linkedContent) });
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
if (this[K_FLAGS].isEnd) {
|
|
629
|
+
return this.broker.publish('event', 'activity.shake.end', cloneContent(message.content), { persistent: false, type: 'shake' });
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const targets = new Map();
|
|
633
|
+
|
|
634
|
+
for (const outboundFlow of this[K_FLOWS].outboundSequenceFlows) {
|
|
635
|
+
const prevTarget = targets.get(outboundFlow.targetId);
|
|
636
|
+
if (!prevTarget) {
|
|
637
|
+
targets.set(outboundFlow.targetId, outboundFlow);
|
|
638
|
+
}
|
|
464
639
|
}
|
|
465
640
|
|
|
466
|
-
for (const
|
|
641
|
+
for (const t of targets.values()) t.shake(message);
|
|
467
642
|
};
|
|
468
643
|
|
|
644
|
+
/** @internal */
|
|
469
645
|
Activity.prototype._consumeInbound = function consumeInbound() {
|
|
470
|
-
if (!this[
|
|
646
|
+
if (!this[K_ACTIVATED]) return;
|
|
471
647
|
|
|
472
|
-
if (this.status || !this
|
|
648
|
+
if (this.status || !this._getInboundTriggers().length) return;
|
|
473
649
|
|
|
474
650
|
const inboundQ = this.broker.getQueue('inbound-q');
|
|
475
|
-
const onInbound = this[
|
|
476
|
-
|
|
477
|
-
if (this[kFlags].isParallelJoin) {
|
|
478
|
-
return inboundQ.assertConsumer(onInbound, { consumerTag: '_run-on-inbound', prefetch: 1000 });
|
|
479
|
-
}
|
|
651
|
+
const onInbound = this[K_MESSAGE_HANDLERS].onInbound;
|
|
480
652
|
|
|
481
653
|
return inboundQ.assertConsumer(onInbound, { consumerTag: '_run-on-inbound' });
|
|
482
654
|
};
|
|
483
655
|
|
|
656
|
+
/** @internal */
|
|
484
657
|
Activity.prototype._onInbound = function onInbound(routingKey, message) {
|
|
485
658
|
message.ack();
|
|
486
659
|
const broker = this.broker;
|
|
@@ -490,6 +663,12 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
|
|
|
490
663
|
const inbound = [cloneContent(content)];
|
|
491
664
|
|
|
492
665
|
switch (routingKey) {
|
|
666
|
+
case 'activity.relink':
|
|
667
|
+
if (content.executionId) this[K_EXEC].set('initExecutionId', content.executionId);
|
|
668
|
+
return this.run({
|
|
669
|
+
message: content.message,
|
|
670
|
+
inbound,
|
|
671
|
+
});
|
|
493
672
|
case 'association.take':
|
|
494
673
|
case 'flow.take':
|
|
495
674
|
case 'activity.restart':
|
|
@@ -498,64 +677,13 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
|
|
|
498
677
|
message: content.message,
|
|
499
678
|
inbound,
|
|
500
679
|
});
|
|
501
|
-
case 'flow.discard':
|
|
502
680
|
case 'activity.discard': {
|
|
503
|
-
|
|
504
|
-
if (content.discardSequence) discardSequence = content.discardSequence.slice();
|
|
505
|
-
return this._runDiscard({ inbound, discardSequence });
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
};
|
|
509
|
-
|
|
510
|
-
Activity.prototype._onJoinInbound = function onJoinInbound(routingKey, message) {
|
|
511
|
-
const { content } = message;
|
|
512
|
-
const { inboundJoinFlows, inboundSourceIds } = this[kFlows];
|
|
513
|
-
let alreadyTouched = false;
|
|
514
|
-
|
|
515
|
-
const touched = new Set();
|
|
516
|
-
|
|
517
|
-
let taken;
|
|
518
|
-
for (const msg of inboundJoinFlows) {
|
|
519
|
-
const sourceId = msg.content.sourceId;
|
|
520
|
-
touched.add(sourceId);
|
|
521
|
-
if (sourceId === content.sourceId) {
|
|
522
|
-
alreadyTouched = true;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
inboundJoinFlows.add(message);
|
|
527
|
-
|
|
528
|
-
if (alreadyTouched) return;
|
|
529
|
-
|
|
530
|
-
const remaining = inboundSourceIds.size - touched.size - 1;
|
|
531
|
-
if (remaining) {
|
|
532
|
-
return this.logger.debug(`<${this.id}> inbound ${message.content.action} from <${message.content.id}>, ${remaining} remaining`);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
const inbound = [];
|
|
536
|
-
for (const im of inboundJoinFlows) {
|
|
537
|
-
if (im.fields.routingKey === 'flow.take') taken = true;
|
|
538
|
-
im.ack();
|
|
539
|
-
inbound.push(cloneContent(im.content));
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
const discardSequence = new Set();
|
|
543
|
-
if (!taken) {
|
|
544
|
-
for (const im of inboundJoinFlows) {
|
|
545
|
-
if (!im.content.discardSequence) continue;
|
|
546
|
-
for (const sourceId of im.content.discardSequence) {
|
|
547
|
-
discardSequence.add(sourceId);
|
|
548
|
-
}
|
|
681
|
+
return this._runDiscard({ inbound });
|
|
549
682
|
}
|
|
550
683
|
}
|
|
551
|
-
|
|
552
|
-
inboundJoinFlows.clear();
|
|
553
|
-
this.broker.cancel('_run-on-inbound');
|
|
554
|
-
|
|
555
|
-
if (!taken) return this._runDiscard({ inbound, discardSequence: [...discardSequence] });
|
|
556
|
-
return this.run({ inbound });
|
|
557
684
|
};
|
|
558
685
|
|
|
686
|
+
/** @internal */
|
|
559
687
|
Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message) {
|
|
560
688
|
const { fields, content, properties } = message;
|
|
561
689
|
const inboundQ = this.broker.getQueue('inbound-q');
|
|
@@ -563,36 +691,54 @@ Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message
|
|
|
563
691
|
switch (routingKey) {
|
|
564
692
|
case 'activity.enter':
|
|
565
693
|
case 'activity.discard': {
|
|
566
|
-
if (content.id === this[
|
|
694
|
+
if (content.id === this[K_FLAGS].attachedTo) {
|
|
567
695
|
inboundQ.queueMessage(fields, cloneContent(content), properties);
|
|
568
696
|
}
|
|
569
697
|
break;
|
|
570
698
|
}
|
|
571
|
-
case 'flow.shake':
|
|
572
|
-
|
|
699
|
+
case 'flow.shake':
|
|
700
|
+
case 'activity.shake.start':
|
|
701
|
+
return this._onShakeMessage(message);
|
|
702
|
+
case 'activity.link': {
|
|
703
|
+
const linkName = content.message?.linkName;
|
|
704
|
+
if (!this[K_FLAGS].linkNames?.includes(linkName)) break;
|
|
705
|
+
const executionId = getUniqueId(this.id);
|
|
706
|
+
this.broker.publish(
|
|
707
|
+
'event',
|
|
708
|
+
'activity.enter',
|
|
709
|
+
cloneContent(content, { id: this.id, type: this.type, executionId, state: 'enter', message: { ...content.message } })
|
|
710
|
+
);
|
|
711
|
+
inboundQ.queueMessage(
|
|
712
|
+
{ routingKey: 'activity.relink' },
|
|
713
|
+
cloneContent(content, { id: this.id, executionId, message: { ...content.message } }),
|
|
714
|
+
properties
|
|
715
|
+
);
|
|
716
|
+
return;
|
|
573
717
|
}
|
|
574
718
|
case 'association.take':
|
|
575
719
|
case 'flow.take':
|
|
576
|
-
case 'flow.discard':
|
|
577
720
|
return inboundQ.queueMessage(fields, cloneContent(content), properties);
|
|
578
721
|
}
|
|
579
722
|
};
|
|
580
723
|
|
|
724
|
+
/** @internal */
|
|
581
725
|
Activity.prototype._consumeRunQ = function consumeRunQ() {
|
|
582
|
-
this[
|
|
583
|
-
this.broker.getQueue('run-q').assertConsumer(this[
|
|
726
|
+
this[K_CONSUMING_RUN_Q] = true;
|
|
727
|
+
this.broker.getQueue('run-q').assertConsumer(this[K_MESSAGE_HANDLERS].onRunMessage, { exclusive: true, consumerTag: '_activity-run' });
|
|
584
728
|
};
|
|
585
729
|
|
|
730
|
+
/** @internal */
|
|
586
731
|
Activity.prototype._pauseRunQ = function pauseRunQ() {
|
|
587
|
-
if (!this[
|
|
732
|
+
if (!this[K_CONSUMING_RUN_Q]) return;
|
|
588
733
|
|
|
589
|
-
this[
|
|
734
|
+
this[K_CONSUMING_RUN_Q] = false;
|
|
590
735
|
this.broker.cancel('_activity-run');
|
|
591
736
|
};
|
|
592
737
|
|
|
738
|
+
/** @internal */
|
|
593
739
|
Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, messageProperties) {
|
|
594
740
|
switch (routingKey) {
|
|
595
|
-
case 'run.
|
|
741
|
+
case 'run.execute.passthrough':
|
|
596
742
|
case 'run.outbound.take':
|
|
597
743
|
case 'run.next':
|
|
598
744
|
return this._continueRunMessage(routingKey, message, messageProperties);
|
|
@@ -614,6 +760,7 @@ Activity.prototype._onRunMessage = function onRunMessage(routingKey, message, me
|
|
|
614
760
|
});
|
|
615
761
|
};
|
|
616
762
|
|
|
763
|
+
/** @internal */
|
|
617
764
|
Activity.prototype._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
618
765
|
const isRedelivered = message.fields.redelivered;
|
|
619
766
|
const content = cloneContent(message.content);
|
|
@@ -621,7 +768,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
621
768
|
|
|
622
769
|
const id = this.id;
|
|
623
770
|
const step = this.environment.settings.step;
|
|
624
|
-
this[
|
|
771
|
+
this[K_STATE_MESSAGE] = message;
|
|
625
772
|
|
|
626
773
|
switch (routingKey) {
|
|
627
774
|
case 'run.enter': {
|
|
@@ -629,7 +776,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
629
776
|
|
|
630
777
|
this.status = 'entered';
|
|
631
778
|
if (!isRedelivered) {
|
|
632
|
-
this[
|
|
779
|
+
this[K_EXEC].delete('execution');
|
|
633
780
|
if (this.extensions) this.extensions.activate(cloneMessage(message));
|
|
634
781
|
this._publishEvent('enter', content, { correlationId });
|
|
635
782
|
}
|
|
@@ -639,7 +786,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
639
786
|
this.logger.debug(`<${id}> discard`, isRedelivered ? 'redelivered' : '');
|
|
640
787
|
|
|
641
788
|
this.status = 'discard';
|
|
642
|
-
this[
|
|
789
|
+
this[K_EXEC].delete('execution');
|
|
643
790
|
|
|
644
791
|
if (this.extensions) this.extensions.activate(cloneMessage(message));
|
|
645
792
|
|
|
@@ -659,20 +806,20 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
659
806
|
break;
|
|
660
807
|
}
|
|
661
808
|
case 'run.execute.passthrough': {
|
|
662
|
-
const execution = this[
|
|
809
|
+
const execution = this[K_EXEC].get('execution');
|
|
663
810
|
if (!isRedelivered && execution) {
|
|
664
811
|
if (execution.completed) return message.ack();
|
|
665
|
-
this[
|
|
812
|
+
this[K_EXECUTE_MESSAGE] = message;
|
|
666
813
|
return execution.passthrough(message);
|
|
667
814
|
}
|
|
668
815
|
}
|
|
669
816
|
case 'run.execute': {
|
|
670
817
|
this.status = 'executing';
|
|
671
|
-
this[
|
|
818
|
+
this[K_EXECUTE_MESSAGE] = message;
|
|
672
819
|
|
|
673
820
|
if (isRedelivered && this.extensions) this.extensions.activate(cloneMessage(message));
|
|
674
821
|
|
|
675
|
-
const exec = this[
|
|
822
|
+
const exec = this[K_EXEC];
|
|
676
823
|
let execution = exec.get('execution');
|
|
677
824
|
if (!execution) {
|
|
678
825
|
execution = new ActivityExecution(this, this.context);
|
|
@@ -681,14 +828,14 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
681
828
|
|
|
682
829
|
this.broker
|
|
683
830
|
.getQueue('execution-q')
|
|
684
|
-
.assertConsumer(this[
|
|
831
|
+
.assertConsumer(this[K_MESSAGE_HANDLERS].onExecutionMessage, { exclusive: true, consumerTag: '_activity-execution' });
|
|
685
832
|
return execution.execute(message);
|
|
686
833
|
}
|
|
687
834
|
case 'run.end': {
|
|
688
835
|
this.logger.debug(`<${id}> end`, isRedelivered ? 'redelivered' : '');
|
|
689
836
|
if (isRedelivered) break;
|
|
690
837
|
|
|
691
|
-
this[
|
|
838
|
+
this[K_COUNTERS].taken++;
|
|
692
839
|
|
|
693
840
|
this.status = 'end';
|
|
694
841
|
|
|
@@ -710,7 +857,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
710
857
|
}
|
|
711
858
|
case 'run.discarded': {
|
|
712
859
|
this.logger.debug(`<${content.executionId} (${id})> discarded`);
|
|
713
|
-
this[
|
|
860
|
+
this[K_COUNTERS].discarded++;
|
|
714
861
|
|
|
715
862
|
this.status = 'discarded';
|
|
716
863
|
content.outbound = undefined;
|
|
@@ -728,11 +875,6 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
728
875
|
message.ack();
|
|
729
876
|
return flow.take(content.flow);
|
|
730
877
|
}
|
|
731
|
-
case 'run.outbound.discard': {
|
|
732
|
-
const flow = this._getOutboundSequenceFlowById(content.flow.id);
|
|
733
|
-
message.ack();
|
|
734
|
-
return flow.discard(content.flow);
|
|
735
|
-
}
|
|
736
878
|
case 'run.leave': {
|
|
737
879
|
this.status = undefined;
|
|
738
880
|
|
|
@@ -754,8 +896,9 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
754
896
|
if (!step) message.ack();
|
|
755
897
|
};
|
|
756
898
|
|
|
899
|
+
/** @internal */
|
|
757
900
|
Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey, message) {
|
|
758
|
-
const executeMessage = this[
|
|
901
|
+
const executeMessage = this[K_EXECUTE_MESSAGE];
|
|
759
902
|
const content = cloneContent({
|
|
760
903
|
...executeMessage.content,
|
|
761
904
|
...message.content,
|
|
@@ -770,7 +913,7 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
|
|
|
770
913
|
|
|
771
914
|
switch (routingKey) {
|
|
772
915
|
case 'execution.outbound.take': {
|
|
773
|
-
return this._doOutbound(message,
|
|
916
|
+
return this._doOutbound(message, (err, outbound) => {
|
|
774
917
|
message.ack();
|
|
775
918
|
if (err) return this.emitFatal(err, content);
|
|
776
919
|
broker.publish('run', 'run.execute.passthrough', cloneContent(content, { outbound }));
|
|
@@ -784,10 +927,11 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
|
|
|
784
927
|
break;
|
|
785
928
|
}
|
|
786
929
|
case 'execution.cancel':
|
|
787
|
-
case 'execution.discard':
|
|
930
|
+
case 'execution.discard': {
|
|
788
931
|
this.status = 'discarded';
|
|
789
932
|
broker.publish('run', 'run.discarded', content, { correlationId });
|
|
790
933
|
break;
|
|
934
|
+
}
|
|
791
935
|
default: {
|
|
792
936
|
this.status = 'executed';
|
|
793
937
|
broker.publish('run', 'run.end', content, { correlationId });
|
|
@@ -798,21 +942,23 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
|
|
|
798
942
|
this._ackRunExecuteMessage();
|
|
799
943
|
};
|
|
800
944
|
|
|
945
|
+
/** @internal */
|
|
801
946
|
Activity.prototype._ackRunExecuteMessage = function ackRunExecuteMessage() {
|
|
802
947
|
if (this.environment.settings.step) return;
|
|
803
|
-
const executeMessage = this[
|
|
948
|
+
const executeMessage = this[K_EXECUTE_MESSAGE];
|
|
804
949
|
executeMessage.ack();
|
|
805
950
|
};
|
|
806
951
|
|
|
952
|
+
/** @internal */
|
|
807
953
|
Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOutbound) {
|
|
808
954
|
const { content, properties } = message;
|
|
809
955
|
const correlationId = properties.correlationId;
|
|
810
|
-
if (content.ignoreOutbound) {
|
|
956
|
+
if (isDiscarded || content.ignoreOutbound) {
|
|
811
957
|
this.broker.publish('run', 'run.leave', cloneContent(content), { correlationId });
|
|
812
958
|
return onOutbound();
|
|
813
959
|
}
|
|
814
960
|
|
|
815
|
-
return this._doOutbound(cloneMessage(message),
|
|
961
|
+
return this._doOutbound(cloneMessage(message), (err, outbound) => {
|
|
816
962
|
if (err) {
|
|
817
963
|
return this._publishEvent('error', { ...content, error: err }, { correlationId });
|
|
818
964
|
}
|
|
@@ -830,39 +976,34 @@ Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOut
|
|
|
830
976
|
});
|
|
831
977
|
};
|
|
832
978
|
|
|
833
|
-
|
|
834
|
-
|
|
979
|
+
/** @internal */
|
|
980
|
+
Activity.prototype._doOutbound = function doOutbound(fromMessage, callback) {
|
|
981
|
+
const outboundSequenceFlows = this[K_FLOWS].outboundSequenceFlows;
|
|
835
982
|
if (!outboundSequenceFlows.length) return callback(null, []);
|
|
836
983
|
|
|
837
984
|
const fromContent = fromMessage.content;
|
|
838
985
|
|
|
839
|
-
let discardSequence = fromContent.discardSequence;
|
|
840
|
-
if (isDiscarded && !discardSequence && this[kFlags].attachedTo && fromContent.inbound?.[0]) {
|
|
841
|
-
discardSequence = [fromContent.inbound[0].id];
|
|
842
|
-
}
|
|
843
|
-
|
|
844
986
|
let outboundFlows;
|
|
845
|
-
if (
|
|
846
|
-
outboundFlows = outboundSequenceFlows.map((flow) => formatFlowAction(flow, { action: 'discard' }));
|
|
847
|
-
} else if (fromContent.outbound?.length) {
|
|
987
|
+
if (fromContent.outbound?.length) {
|
|
848
988
|
outboundFlows = outboundSequenceFlows.map((flow) => formatFlowAction(flow, fromContent.outbound.filter((f) => f.id === flow.id).pop()));
|
|
849
989
|
}
|
|
850
990
|
|
|
851
991
|
if (outboundFlows) {
|
|
852
|
-
this._doRunOutbound(outboundFlows, fromContent
|
|
992
|
+
this._doRunOutbound(outboundFlows, fromContent);
|
|
853
993
|
return callback(null, outboundFlows);
|
|
854
994
|
}
|
|
855
995
|
|
|
856
996
|
return this.evaluateOutbound(fromMessage, fromContent.outboundTakeOne, (err, evaluatedOutbound) => {
|
|
857
997
|
if (err) return callback(new ActivityError(err.message, fromMessage, err));
|
|
858
|
-
const outbound = this._doRunOutbound(evaluatedOutbound, fromContent
|
|
998
|
+
const outbound = this._doRunOutbound(evaluatedOutbound, fromContent);
|
|
859
999
|
return callback(null, outbound);
|
|
860
1000
|
});
|
|
861
1001
|
};
|
|
862
1002
|
|
|
863
|
-
|
|
1003
|
+
/** @internal */
|
|
1004
|
+
Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content) {
|
|
864
1005
|
if (outboundList.length === 1) {
|
|
865
|
-
this._publishRunOutbound(outboundList[0], content
|
|
1006
|
+
this._publishRunOutbound(outboundList[0], content);
|
|
866
1007
|
} else {
|
|
867
1008
|
const targets = new Map();
|
|
868
1009
|
|
|
@@ -876,15 +1017,21 @@ Activity.prototype._doRunOutbound = function doRunOutbound(outboundList, content
|
|
|
876
1017
|
}
|
|
877
1018
|
|
|
878
1019
|
for (const outboundFlow of targets.values()) {
|
|
879
|
-
this._publishRunOutbound(outboundFlow, content
|
|
1020
|
+
this._publishRunOutbound(outboundFlow, content);
|
|
880
1021
|
}
|
|
881
1022
|
}
|
|
882
1023
|
|
|
883
1024
|
return outboundList;
|
|
884
1025
|
};
|
|
885
1026
|
|
|
886
|
-
|
|
1027
|
+
/** @internal */
|
|
1028
|
+
Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlow, content) {
|
|
887
1029
|
const { id: flowId, action, result } = outboundFlow;
|
|
1030
|
+
|
|
1031
|
+
if (action === 'discard') {
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
888
1035
|
this.broker.publish(
|
|
889
1036
|
'run',
|
|
890
1037
|
'run.outbound.' + action,
|
|
@@ -893,16 +1040,16 @@ Activity.prototype._publishRunOutbound = function publishRunOutbound(outboundFlo
|
|
|
893
1040
|
...(result && typeof result === 'object' && result),
|
|
894
1041
|
...outboundFlow,
|
|
895
1042
|
sequenceId: getUniqueId(`${flowId}_${action}`),
|
|
896
|
-
...(discardSequence && { discardSequence: discardSequence.slice() }),
|
|
897
1043
|
},
|
|
898
1044
|
})
|
|
899
1045
|
);
|
|
900
1046
|
};
|
|
901
1047
|
|
|
1048
|
+
/** @internal */
|
|
902
1049
|
Activity.prototype._onResumeMessage = function onResumeMessage(message) {
|
|
903
1050
|
message.ack();
|
|
904
1051
|
|
|
905
|
-
const stateMessage = this[
|
|
1052
|
+
const stateMessage = this[K_STATE_MESSAGE];
|
|
906
1053
|
const fields = stateMessage.fields;
|
|
907
1054
|
if (!fields.redelivered) return;
|
|
908
1055
|
|
|
@@ -924,6 +1071,7 @@ Activity.prototype._onResumeMessage = function onResumeMessage(message) {
|
|
|
924
1071
|
return this.broker.publish('run', fields.routingKey, cloneContent(stateMessage.content), stateMessage.properties);
|
|
925
1072
|
};
|
|
926
1073
|
|
|
1074
|
+
/** @internal */
|
|
927
1075
|
Activity.prototype._publishEvent = function publishEvent(state, content, properties) {
|
|
928
1076
|
this.broker.publish('event', `activity.${state}`, cloneContent(content, { state }), {
|
|
929
1077
|
...properties,
|
|
@@ -932,12 +1080,13 @@ Activity.prototype._publishEvent = function publishEvent(state, content, propert
|
|
|
932
1080
|
});
|
|
933
1081
|
};
|
|
934
1082
|
|
|
1083
|
+
/** @internal */
|
|
935
1084
|
Activity.prototype._onStop = function onStop(message) {
|
|
936
|
-
const running = this[
|
|
1085
|
+
const running = this[K_CONSUMING];
|
|
937
1086
|
|
|
938
1087
|
this.stopped = true;
|
|
939
1088
|
|
|
940
|
-
this[
|
|
1089
|
+
this[K_CONSUMING] = false;
|
|
941
1090
|
const broker = this.broker;
|
|
942
1091
|
this._pauseRunQ();
|
|
943
1092
|
broker.cancel('_activity-api');
|
|
@@ -952,18 +1101,20 @@ Activity.prototype._onStop = function onStop(message) {
|
|
|
952
1101
|
}
|
|
953
1102
|
};
|
|
954
1103
|
|
|
1104
|
+
/** @internal */
|
|
955
1105
|
Activity.prototype._consumeApi = function consumeApi() {
|
|
956
|
-
const executionId = this[
|
|
1106
|
+
const executionId = this[K_EXEC].get('executionId');
|
|
957
1107
|
if (!executionId) return;
|
|
958
1108
|
const broker = this.broker;
|
|
959
1109
|
broker.cancel('_activity-api');
|
|
960
|
-
broker.subscribeTmp('api', `activity.*.${executionId}`, this[
|
|
1110
|
+
broker.subscribeTmp('api', `activity.*.${executionId}`, this[K_MESSAGE_HANDLERS].onApiMessage, {
|
|
961
1111
|
noAck: true,
|
|
962
1112
|
consumerTag: '_activity-api',
|
|
963
1113
|
priority: 100,
|
|
964
1114
|
});
|
|
965
1115
|
};
|
|
966
1116
|
|
|
1117
|
+
/** @internal */
|
|
967
1118
|
Activity.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
968
1119
|
switch (message.properties.type) {
|
|
969
1120
|
case 'discard': {
|
|
@@ -978,6 +1129,7 @@ Activity.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
|
978
1129
|
}
|
|
979
1130
|
};
|
|
980
1131
|
|
|
1132
|
+
/** @internal */
|
|
981
1133
|
Activity.prototype._createMessage = function createMessage(override) {
|
|
982
1134
|
const { name, status, parent } = this;
|
|
983
1135
|
|
|
@@ -990,21 +1142,23 @@ Activity.prototype._createMessage = function createMessage(override) {
|
|
|
990
1142
|
...(parent && { parent: cloneParent(parent) }),
|
|
991
1143
|
};
|
|
992
1144
|
|
|
993
|
-
for (const [flag, value] of Object.entries(this[
|
|
1145
|
+
for (const [flag, value] of Object.entries(this[K_FLAGS])) {
|
|
994
1146
|
if (value) result[flag] = value;
|
|
995
1147
|
}
|
|
996
1148
|
|
|
997
1149
|
return result;
|
|
998
1150
|
};
|
|
999
1151
|
|
|
1152
|
+
/** @internal */
|
|
1000
1153
|
Activity.prototype._getOutboundSequenceFlowById = function getOutboundSequenceFlowById(flowId) {
|
|
1001
|
-
return this[
|
|
1154
|
+
return this[K_FLOWS].outboundSequenceFlows.find((flow) => flow.id === flowId);
|
|
1002
1155
|
};
|
|
1003
1156
|
|
|
1157
|
+
/** @internal */
|
|
1004
1158
|
Activity.prototype._deactivateRunConsumers = function _deactivateRunConsumers() {
|
|
1005
1159
|
const broker = this.broker;
|
|
1006
1160
|
broker.cancel('_activity-api');
|
|
1007
1161
|
this._pauseRunQ();
|
|
1008
1162
|
broker.cancel('_activity-execution');
|
|
1009
|
-
this[
|
|
1163
|
+
this[K_CONSUMING] = false;
|
|
1010
1164
|
};
|