bpmn-elements 18.0.1 → 18.0.2
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/dist/activity/Activity.js +63 -57
- package/dist/events/BoundaryEvent.js +2 -2
- package/dist/gateways/ParallelGateway.js +29 -9
- package/dist/process/ProcessExecution.js +2 -2
- package/package.json +1 -1
- package/src/activity/Activity.js +48 -47
- package/src/events/BoundaryEvent.js +2 -2
- package/src/gateways/ParallelGateway.js +25 -10
- package/src/process/ProcessExecution.js +2 -2
- package/types/index.d.ts +41 -16
|
@@ -97,8 +97,9 @@ function Activity(Behaviour, activityDef, context) {
|
|
|
97
97
|
outboundSequenceFlows,
|
|
98
98
|
outboundEvaluator: new _outboundEvaluator.OutboundEvaluator(this, outboundSequenceFlows)
|
|
99
99
|
};
|
|
100
|
+
const isThrowingLink = activityDef.isThrowing && activityDef.linkNames?.length;
|
|
100
101
|
this[K_FLAGS] = {
|
|
101
|
-
isEnd: !outboundSequenceFlows.length,
|
|
102
|
+
isEnd: !outboundSequenceFlows.length && !isThrowingLink,
|
|
102
103
|
isStart: !hasInboundTrigger && !behaviour.triggeredByEvent && !activityDef.isCatching,
|
|
103
104
|
isSubProcess: activityDef.isSubProcess,
|
|
104
105
|
isMultiInstance: !!behaviour.loopCharacteristics,
|
|
@@ -268,7 +269,7 @@ Object.defineProperties(Activity.prototype, {
|
|
|
268
269
|
},
|
|
269
270
|
initialized: {
|
|
270
271
|
get() {
|
|
271
|
-
return
|
|
272
|
+
return this[K_EXEC].get('initialized') > 0;
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
});
|
|
@@ -280,7 +281,23 @@ Object.defineProperties(Activity.prototype, {
|
|
|
280
281
|
Activity.prototype.activate = function activate() {
|
|
281
282
|
if (this[_constants.K_ACTIVATED]) return;
|
|
282
283
|
this[_constants.K_ACTIVATED] = true;
|
|
283
|
-
|
|
284
|
+
this.addInboundListeners();
|
|
285
|
+
return this.consumeInbound();
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Assert the inbound queue consumer when the activity has a trigger or is initialized.
|
|
290
|
+
* Idempotent: asserting the consumer again while one is active is a no-op.
|
|
291
|
+
* @returns {void}
|
|
292
|
+
*/
|
|
293
|
+
Activity.prototype.consumeInbound = function consumeInbound() {
|
|
294
|
+
if (!this[_constants.K_ACTIVATED]) return;
|
|
295
|
+
if (this.status) return;
|
|
296
|
+
if (!this._getInboundTriggers().length && !this.initialized) return;
|
|
297
|
+
const onInbound = this[_constants.K_MESSAGE_HANDLERS].onInbound;
|
|
298
|
+
return this.broker.getQueue('inbound-q').assertConsumer(onInbound, {
|
|
299
|
+
consumerTag: '_run-on-inbound'
|
|
300
|
+
});
|
|
284
301
|
};
|
|
285
302
|
|
|
286
303
|
/** @internal */
|
|
@@ -326,17 +343,28 @@ Activity.prototype.deactivate = function deactivate() {
|
|
|
326
343
|
/**
|
|
327
344
|
* Initialise activity executionId and emit init event without starting the run.
|
|
328
345
|
* @param {Record<string, any>} [initContent] Optional content merged into the init message
|
|
346
|
+
* @param {import('smqp').MessageProperties} [properties] Optional message properties merged into the init message properties
|
|
329
347
|
*/
|
|
330
|
-
Activity.prototype.init = function init(initContent) {
|
|
348
|
+
Activity.prototype.init = function init(initContent, properties) {
|
|
331
349
|
const id = this.id;
|
|
332
350
|
const exec = this[K_EXEC];
|
|
333
|
-
|
|
334
|
-
|
|
351
|
+
exec.set('initialized', (exec.get('initialized') || 0) + 1);
|
|
352
|
+
const executionId = (0, _shared.getUniqueId)(id);
|
|
335
353
|
this.logger.debug(`<${id}> initialized with executionId <${executionId}>`);
|
|
336
354
|
this._publishEvent('init', this._createMessage({
|
|
337
355
|
...initContent,
|
|
338
356
|
executionId
|
|
339
357
|
}));
|
|
358
|
+
this.broker.getQueue('inbound-q').queueMessage({
|
|
359
|
+
routingKey: 'activity.init'
|
|
360
|
+
}, {
|
|
361
|
+
...initContent,
|
|
362
|
+
id,
|
|
363
|
+
executionId
|
|
364
|
+
}, {
|
|
365
|
+
persistent: false,
|
|
366
|
+
...properties
|
|
367
|
+
});
|
|
340
368
|
};
|
|
341
369
|
|
|
342
370
|
/**
|
|
@@ -347,13 +375,15 @@ Activity.prototype.init = function init(initContent) {
|
|
|
347
375
|
Activity.prototype.run = function run(runContent) {
|
|
348
376
|
const id = this.id;
|
|
349
377
|
if (this.isRunning) throw new Error(`activity <${id}> is already running`);
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
378
|
+
const {
|
|
379
|
+
initExecutionId,
|
|
380
|
+
...runMessage
|
|
381
|
+
} = runContent || {};
|
|
382
|
+
const executionId = runMessage?.id === id && initExecutionId ? initExecutionId : (0, _shared.getUniqueId)(id);
|
|
383
|
+
this[K_EXEC].set('executionId', executionId);
|
|
354
384
|
this._consumeApi();
|
|
355
385
|
const content = this._createMessage({
|
|
356
|
-
...
|
|
386
|
+
...runMessage,
|
|
357
387
|
executionId
|
|
358
388
|
});
|
|
359
389
|
const broker = this.broker;
|
|
@@ -558,10 +588,8 @@ Activity.prototype.getActivityById = function getActivityById(elementId) {
|
|
|
558
588
|
|
|
559
589
|
/** @internal */
|
|
560
590
|
Activity.prototype._runDiscard = function runDiscard(discardContent) {
|
|
561
|
-
const
|
|
562
|
-
|
|
563
|
-
exec.set('executionId', executionId);
|
|
564
|
-
exec.delete('initExecutionId');
|
|
591
|
+
const executionId = (0, _shared.getUniqueId)(this.id);
|
|
592
|
+
this[K_EXEC].set('executionId', executionId);
|
|
565
593
|
this._consumeApi();
|
|
566
594
|
const content = this._createMessage({
|
|
567
595
|
...discardContent,
|
|
@@ -613,7 +641,7 @@ Activity.prototype._onShakeMessage = function _onShakeMessage(sourceMessage) {
|
|
|
613
641
|
id: this.id,
|
|
614
642
|
type: this.type
|
|
615
643
|
});
|
|
616
|
-
return this.broker.publish('event', 'activity.shake.
|
|
644
|
+
return this.broker.publish('event', 'activity.shake.converge', message.content, {
|
|
617
645
|
persistent: false,
|
|
618
646
|
type: 'shake'
|
|
619
647
|
});
|
|
@@ -674,43 +702,38 @@ Activity.prototype._shakeOutbound = function shakeOutbound(sourceMessage) {
|
|
|
674
702
|
for (const t of targets.values()) t.shake(message);
|
|
675
703
|
};
|
|
676
704
|
|
|
677
|
-
/** @internal */
|
|
678
|
-
Activity.prototype._consumeInbound = function consumeInbound() {
|
|
679
|
-
if (!this[_constants.K_ACTIVATED]) return;
|
|
680
|
-
if (this.status || !this._getInboundTriggers().length) return;
|
|
681
|
-
const inboundQ = this.broker.getQueue('inbound-q');
|
|
682
|
-
const onInbound = this[_constants.K_MESSAGE_HANDLERS].onInbound;
|
|
683
|
-
return inboundQ.assertConsumer(onInbound, {
|
|
684
|
-
consumerTag: '_run-on-inbound'
|
|
685
|
-
});
|
|
686
|
-
};
|
|
687
|
-
|
|
688
705
|
/** @internal */
|
|
689
706
|
Activity.prototype._onInbound = function onInbound(routingKey, message) {
|
|
690
707
|
message.ack();
|
|
691
708
|
const broker = this.broker;
|
|
692
709
|
broker.cancel('_run-on-inbound');
|
|
693
710
|
const content = message.content;
|
|
694
|
-
const inbound = [(0, _messageHelper.cloneContent)(content)];
|
|
695
711
|
switch (routingKey) {
|
|
696
|
-
case 'activity.
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
712
|
+
case 'activity.init':
|
|
713
|
+
{
|
|
714
|
+
const exec = this[K_EXEC];
|
|
715
|
+
exec.set('initialized', (exec.get('initialized') || 0) - 1);
|
|
716
|
+
return this.run({
|
|
717
|
+
initExecutionId: content.executionId,
|
|
718
|
+
id: content.id,
|
|
719
|
+
message: content.message,
|
|
720
|
+
...(content.inbound?.length && {
|
|
721
|
+
inbound: content.inbound
|
|
722
|
+
})
|
|
723
|
+
});
|
|
724
|
+
}
|
|
702
725
|
case 'association.take':
|
|
703
726
|
case 'flow.take':
|
|
704
727
|
case 'activity.restart':
|
|
705
728
|
case 'activity.enter':
|
|
706
729
|
return this.run({
|
|
707
730
|
message: content.message,
|
|
708
|
-
inbound
|
|
731
|
+
inbound: [(0, _messageHelper.cloneContent)(content)]
|
|
709
732
|
});
|
|
710
733
|
case 'activity.discard':
|
|
711
734
|
{
|
|
712
735
|
return this._runDiscard({
|
|
713
|
-
inbound
|
|
736
|
+
inbound: [(0, _messageHelper.cloneContent)(content)]
|
|
714
737
|
});
|
|
715
738
|
}
|
|
716
739
|
}
|
|
@@ -740,26 +763,9 @@ Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message
|
|
|
740
763
|
{
|
|
741
764
|
const linkName = content.message?.linkName;
|
|
742
765
|
if (!this[K_FLAGS].linkNames?.includes(linkName)) break;
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
type: this.type,
|
|
747
|
-
executionId,
|
|
748
|
-
state: 'enter',
|
|
749
|
-
message: {
|
|
750
|
-
...content.message
|
|
751
|
-
}
|
|
752
|
-
}));
|
|
753
|
-
inboundQ.queueMessage({
|
|
754
|
-
routingKey: 'activity.relink'
|
|
755
|
-
}, (0, _messageHelper.cloneContent)(content, {
|
|
756
|
-
id: this.id,
|
|
757
|
-
executionId,
|
|
758
|
-
message: {
|
|
759
|
-
...content.message
|
|
760
|
-
}
|
|
761
|
-
}), properties);
|
|
762
|
-
return;
|
|
766
|
+
return this.init({
|
|
767
|
+
inbound: [(0, _messageHelper.cloneContent)(content)]
|
|
768
|
+
});
|
|
763
769
|
}
|
|
764
770
|
case 'association.take':
|
|
765
771
|
case 'flow.take':
|
|
@@ -942,7 +948,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
942
948
|
case 'run.next':
|
|
943
949
|
message.ack();
|
|
944
950
|
this._pauseRunQ();
|
|
945
|
-
return this.
|
|
951
|
+
return this.consumeInbound();
|
|
946
952
|
}
|
|
947
953
|
if (!step) message.ack();
|
|
948
954
|
};
|
|
@@ -44,9 +44,9 @@ Object.defineProperty(BoundaryEventBehaviour.prototype, 'executionId', {
|
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
46
|
Object.defineProperty(BoundaryEventBehaviour.prototype, 'cancelActivity', {
|
|
47
|
+
/** @returns {boolean} */
|
|
47
48
|
get() {
|
|
48
|
-
|
|
49
|
-
return 'cancelActivity' in behaviour ? behaviour.cancelActivity : true;
|
|
49
|
+
return this.activity.behaviour?.cancelActivity ?? true;
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
52
|
|
|
@@ -76,11 +76,15 @@ function ParallelGatewayBehaviour(activity) {
|
|
|
76
76
|
this.type = activity.type;
|
|
77
77
|
this.activity = activity;
|
|
78
78
|
this.broker = activity.broker;
|
|
79
|
+
/**
|
|
80
|
+
* Inbound taken sequence flow sequences
|
|
81
|
+
* @type {Set<import('#types').ElementMessageContent}
|
|
82
|
+
*/
|
|
79
83
|
this.inbound = new Set();
|
|
80
|
-
this.isConverging = true;
|
|
81
84
|
this[_constants.K_EXECUTE_MESSAGE] = undefined;
|
|
82
85
|
}
|
|
83
86
|
Object.defineProperty(ParallelGatewayBehaviour.prototype, 'executionId', {
|
|
87
|
+
/** @returns {string | undefined} */
|
|
84
88
|
get() {
|
|
85
89
|
return this[_constants.K_EXECUTE_MESSAGE]?.content.executionId;
|
|
86
90
|
}
|
|
@@ -110,6 +114,12 @@ ParallelGatewayBehaviour.prototype.execute = function execute(executeMessage) {
|
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Setup peer monitor
|
|
120
|
+
* @param {import('#types').ElementBrokerMessage} executeMessage
|
|
121
|
+
* @returns {void}
|
|
122
|
+
*/
|
|
113
123
|
ParallelGatewayBehaviour.prototype.setup = function setup(executeMessage) {
|
|
114
124
|
const peerIds = new Set([...this.activity[K_PEERS].values()].map(v => [...v]).flat());
|
|
115
125
|
this[_constants.K_TARGETS] = new Map([...peerIds].map(pid => [pid, this.activity.getActivityById(pid)]));
|
|
@@ -142,9 +152,7 @@ ParallelGatewayBehaviour.prototype.setup = function setup(executeMessage) {
|
|
|
142
152
|
exclusive: true,
|
|
143
153
|
prefetch: 10000
|
|
144
154
|
});
|
|
145
|
-
|
|
146
|
-
this.broker.publish('event', 'activity.converge', (0, _messageHelper.cloneContent)(executeContent));
|
|
147
|
-
}
|
|
155
|
+
this.broker.publish('event', 'activity.converge', (0, _messageHelper.cloneContent)(executeContent));
|
|
148
156
|
return this.broker.publish('execution', 'execute.start', (0, _messageHelper.cloneContent)(executeMessage.content, {
|
|
149
157
|
preventComplete: true,
|
|
150
158
|
state: STATE_SETUP
|
|
@@ -179,17 +187,19 @@ ParallelGatewayBehaviour.prototype._stop = function stop() {
|
|
|
179
187
|
this.broker.cancel('_parallel-execution-peer-enter-tag');
|
|
180
188
|
this.peerMonitor.stop();
|
|
181
189
|
};
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Peer monitor
|
|
193
|
+
* @param {import('#types').Activity} activity parallel gateway activity
|
|
194
|
+
* @param {Map<string, import('#types').Activity} targets parallel gateway peer target activities
|
|
195
|
+
*/
|
|
182
196
|
function PeerMonitor(activity, targets) {
|
|
183
197
|
this.activity = activity;
|
|
184
198
|
this.id = activity.id;
|
|
185
199
|
this.broker = activity.broker;
|
|
186
|
-
this.running = 0;
|
|
187
|
-
this.index = 0;
|
|
188
|
-
this.discarded = 0;
|
|
189
200
|
this.running = new Map();
|
|
190
201
|
this.watching = new Map();
|
|
191
202
|
this.targets = targets;
|
|
192
|
-
this.touched = new Set();
|
|
193
203
|
this.inbound = [];
|
|
194
204
|
}
|
|
195
205
|
Object.defineProperty(PeerMonitor.prototype, 'isRunning', {
|
|
@@ -197,6 +207,12 @@ Object.defineProperty(PeerMonitor.prototype, 'isRunning', {
|
|
|
197
207
|
return this.running.size > 0;
|
|
198
208
|
}
|
|
199
209
|
});
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Execute peer monitor
|
|
213
|
+
* @param {import('#types').ElementBrokerMessage} executeMessage
|
|
214
|
+
* @returns {number} number of running peers
|
|
215
|
+
*/
|
|
200
216
|
PeerMonitor.prototype.execute = function execute(executeMessage) {
|
|
201
217
|
const message = (0, _messageHelper.cloneMessage)(executeMessage);
|
|
202
218
|
const inbound = message.content.inbound.pop();
|
|
@@ -208,12 +224,16 @@ PeerMonitor.prototype.execute = function execute(executeMessage) {
|
|
|
208
224
|
state: STATE_MONTITORING,
|
|
209
225
|
preventComplete: true
|
|
210
226
|
});
|
|
211
|
-
this.touched.add(inbound.sourceId);
|
|
212
227
|
for (const target of this.targets.values()) {
|
|
213
228
|
this.monitor(target);
|
|
214
229
|
}
|
|
215
230
|
return this.running.size;
|
|
216
231
|
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Monitor peer activity
|
|
235
|
+
* @param {import('#types').Activity} peerActivity
|
|
236
|
+
*/
|
|
217
237
|
PeerMonitor.prototype.monitor = function monitor(peerActivity) {
|
|
218
238
|
if (this.watching.has(peerActivity.id)) return;
|
|
219
239
|
this.activity.logger.debug(`<${this.id}> monitor <${peerActivity.id}> with status: ${peerActivity.status}`);
|
|
@@ -391,7 +391,7 @@ ProcessExecution.prototype._start = function start() {
|
|
|
391
391
|
this._shakeOnStart();
|
|
392
392
|
for (const a of startActivities) a.init();
|
|
393
393
|
this[_constants.K_STATUS] = 'executing';
|
|
394
|
-
for (const a of startActivities) a.
|
|
394
|
+
for (const a of startActivities) a.consumeInbound();
|
|
395
395
|
if (!startActivities.size) {
|
|
396
396
|
for (const a of this[K_ELEMENTS].triggeredByEvent) {
|
|
397
397
|
if (a.isCatching && !a.isRunning) a.run();
|
|
@@ -556,7 +556,7 @@ ProcessExecution.prototype._shakeElements = function shakeElements(fromId) {
|
|
|
556
556
|
}) => {
|
|
557
557
|
if (content.parent.id !== this.id) return;
|
|
558
558
|
switch (routingKey) {
|
|
559
|
-
case 'activity.shake.
|
|
559
|
+
case 'activity.shake.converge':
|
|
560
560
|
{
|
|
561
561
|
const join = convergingGateways.get(content.join);
|
|
562
562
|
if (!join) {
|
package/package.json
CHANGED
package/src/activity/Activity.js
CHANGED
|
@@ -91,8 +91,10 @@ export function Activity(Behaviour, activityDef, context) {
|
|
|
91
91
|
outboundEvaluator: new OutboundEvaluator(this, outboundSequenceFlows),
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
+
const isThrowingLink = activityDef.isThrowing && activityDef.linkNames?.length;
|
|
95
|
+
|
|
94
96
|
this[K_FLAGS] = {
|
|
95
|
-
isEnd: !outboundSequenceFlows.length,
|
|
97
|
+
isEnd: !outboundSequenceFlows.length && !isThrowingLink,
|
|
96
98
|
isStart: !hasInboundTrigger && !behaviour.triggeredByEvent && !activityDef.isCatching,
|
|
97
99
|
isSubProcess: activityDef.isSubProcess,
|
|
98
100
|
isMultiInstance: !!behaviour.loopCharacteristics,
|
|
@@ -262,7 +264,7 @@ Object.defineProperties(Activity.prototype, {
|
|
|
262
264
|
},
|
|
263
265
|
initialized: {
|
|
264
266
|
get() {
|
|
265
|
-
return
|
|
267
|
+
return this[K_EXEC].get('initialized') > 0;
|
|
266
268
|
},
|
|
267
269
|
},
|
|
268
270
|
});
|
|
@@ -274,7 +276,25 @@ Object.defineProperties(Activity.prototype, {
|
|
|
274
276
|
Activity.prototype.activate = function activate() {
|
|
275
277
|
if (this[K_ACTIVATED]) return;
|
|
276
278
|
this[K_ACTIVATED] = true;
|
|
277
|
-
|
|
279
|
+
this.addInboundListeners();
|
|
280
|
+
return this.consumeInbound();
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Assert the inbound queue consumer when the activity has a trigger or is initialized.
|
|
285
|
+
* Idempotent: asserting the consumer again while one is active is a no-op.
|
|
286
|
+
* @returns {void}
|
|
287
|
+
*/
|
|
288
|
+
Activity.prototype.consumeInbound = function consumeInbound() {
|
|
289
|
+
if (!this[K_ACTIVATED]) return;
|
|
290
|
+
|
|
291
|
+
if (this.status) return;
|
|
292
|
+
|
|
293
|
+
if (!this._getInboundTriggers().length && !this.initialized) return;
|
|
294
|
+
|
|
295
|
+
const onInbound = this[K_MESSAGE_HANDLERS].onInbound;
|
|
296
|
+
|
|
297
|
+
return this.broker.getQueue('inbound-q').assertConsumer(onInbound, { consumerTag: '_run-on-inbound' });
|
|
278
298
|
};
|
|
279
299
|
|
|
280
300
|
/** @internal */
|
|
@@ -319,14 +339,18 @@ Activity.prototype.deactivate = function deactivate() {
|
|
|
319
339
|
/**
|
|
320
340
|
* Initialise activity executionId and emit init event without starting the run.
|
|
321
341
|
* @param {Record<string, any>} [initContent] Optional content merged into the init message
|
|
342
|
+
* @param {import('smqp').MessageProperties} [properties] Optional message properties merged into the init message properties
|
|
322
343
|
*/
|
|
323
|
-
Activity.prototype.init = function init(initContent) {
|
|
344
|
+
Activity.prototype.init = function init(initContent, properties) {
|
|
324
345
|
const id = this.id;
|
|
325
346
|
const exec = this[K_EXEC];
|
|
326
|
-
|
|
327
|
-
|
|
347
|
+
exec.set('initialized', (exec.get('initialized') || 0) + 1);
|
|
348
|
+
const executionId = getUniqueId(id);
|
|
328
349
|
this.logger.debug(`<${id}> initialized with executionId <${executionId}>`);
|
|
329
350
|
this._publishEvent('init', this._createMessage({ ...initContent, executionId }));
|
|
351
|
+
this.broker
|
|
352
|
+
.getQueue('inbound-q')
|
|
353
|
+
.queueMessage({ routingKey: 'activity.init' }, { ...initContent, id, executionId }, { persistent: false, ...properties });
|
|
330
354
|
};
|
|
331
355
|
|
|
332
356
|
/**
|
|
@@ -338,14 +362,13 @@ Activity.prototype.run = function run(runContent) {
|
|
|
338
362
|
const id = this.id;
|
|
339
363
|
if (this.isRunning) throw new Error(`activity <${id}> is already running`);
|
|
340
364
|
|
|
341
|
-
const
|
|
342
|
-
const executionId =
|
|
343
|
-
|
|
344
|
-
exec.delete('initExecutionId');
|
|
365
|
+
const { initExecutionId, ...runMessage } = runContent || {};
|
|
366
|
+
const executionId = runMessage?.id === id && initExecutionId ? initExecutionId : getUniqueId(id);
|
|
367
|
+
this[K_EXEC].set('executionId', executionId);
|
|
345
368
|
|
|
346
369
|
this._consumeApi();
|
|
347
370
|
|
|
348
|
-
const content = this._createMessage({ ...
|
|
371
|
+
const content = this._createMessage({ ...runMessage, executionId });
|
|
349
372
|
const broker = this.broker;
|
|
350
373
|
|
|
351
374
|
broker.publish('run', 'run.enter', content);
|
|
@@ -541,10 +564,8 @@ Activity.prototype.getActivityById = function getActivityById(elementId) {
|
|
|
541
564
|
|
|
542
565
|
/** @internal */
|
|
543
566
|
Activity.prototype._runDiscard = function runDiscard(discardContent) {
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
exec.set('executionId', executionId);
|
|
547
|
-
exec.delete('initExecutionId');
|
|
567
|
+
const executionId = getUniqueId(this.id);
|
|
568
|
+
this[K_EXEC].set('executionId', executionId);
|
|
548
569
|
|
|
549
570
|
this._consumeApi();
|
|
550
571
|
|
|
@@ -594,7 +615,7 @@ Activity.prototype._onShakeMessage = function _onShakeMessage(sourceMessage) {
|
|
|
594
615
|
if (this[K_FLAGS].isParallelGateway) {
|
|
595
616
|
const message = cloneMessage(sourceMessage, { join: this.id });
|
|
596
617
|
message.content.sequence.push({ id: this.id, type: this.type });
|
|
597
|
-
return this.broker.publish('event', 'activity.shake.
|
|
618
|
+
return this.broker.publish('event', 'activity.shake.converge', message.content, {
|
|
598
619
|
persistent: false,
|
|
599
620
|
type: 'shake',
|
|
600
621
|
});
|
|
@@ -641,18 +662,6 @@ Activity.prototype._shakeOutbound = function shakeOutbound(sourceMessage) {
|
|
|
641
662
|
for (const t of targets.values()) t.shake(message);
|
|
642
663
|
};
|
|
643
664
|
|
|
644
|
-
/** @internal */
|
|
645
|
-
Activity.prototype._consumeInbound = function consumeInbound() {
|
|
646
|
-
if (!this[K_ACTIVATED]) return;
|
|
647
|
-
|
|
648
|
-
if (this.status || !this._getInboundTriggers().length) return;
|
|
649
|
-
|
|
650
|
-
const inboundQ = this.broker.getQueue('inbound-q');
|
|
651
|
-
const onInbound = this[K_MESSAGE_HANDLERS].onInbound;
|
|
652
|
-
|
|
653
|
-
return inboundQ.assertConsumer(onInbound, { consumerTag: '_run-on-inbound' });
|
|
654
|
-
};
|
|
655
|
-
|
|
656
665
|
/** @internal */
|
|
657
666
|
Activity.prototype._onInbound = function onInbound(routingKey, message) {
|
|
658
667
|
message.ack();
|
|
@@ -660,25 +669,28 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
|
|
|
660
669
|
broker.cancel('_run-on-inbound');
|
|
661
670
|
|
|
662
671
|
const content = message.content;
|
|
663
|
-
const inbound = [cloneContent(content)];
|
|
664
672
|
|
|
665
673
|
switch (routingKey) {
|
|
666
|
-
case 'activity.
|
|
667
|
-
|
|
674
|
+
case 'activity.init': {
|
|
675
|
+
const exec = this[K_EXEC];
|
|
676
|
+
exec.set('initialized', (exec.get('initialized') || 0) - 1);
|
|
668
677
|
return this.run({
|
|
678
|
+
initExecutionId: content.executionId,
|
|
679
|
+
id: content.id,
|
|
669
680
|
message: content.message,
|
|
670
|
-
inbound,
|
|
681
|
+
...(content.inbound?.length && { inbound: content.inbound }),
|
|
671
682
|
});
|
|
683
|
+
}
|
|
672
684
|
case 'association.take':
|
|
673
685
|
case 'flow.take':
|
|
674
686
|
case 'activity.restart':
|
|
675
687
|
case 'activity.enter':
|
|
676
688
|
return this.run({
|
|
677
689
|
message: content.message,
|
|
678
|
-
inbound,
|
|
690
|
+
inbound: [cloneContent(content)],
|
|
679
691
|
});
|
|
680
692
|
case 'activity.discard': {
|
|
681
|
-
return this._runDiscard({ inbound });
|
|
693
|
+
return this._runDiscard({ inbound: [cloneContent(content)] });
|
|
682
694
|
}
|
|
683
695
|
}
|
|
684
696
|
};
|
|
@@ -702,18 +714,7 @@ Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message
|
|
|
702
714
|
case 'activity.link': {
|
|
703
715
|
const linkName = content.message?.linkName;
|
|
704
716
|
if (!this[K_FLAGS].linkNames?.includes(linkName)) break;
|
|
705
|
-
|
|
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;
|
|
717
|
+
return this.init({ inbound: [cloneContent(content)] });
|
|
717
718
|
}
|
|
718
719
|
case 'association.take':
|
|
719
720
|
case 'flow.take':
|
|
@@ -890,7 +891,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
|
|
|
890
891
|
case 'run.next':
|
|
891
892
|
message.ack();
|
|
892
893
|
this._pauseRunQ();
|
|
893
|
-
return this.
|
|
894
|
+
return this.consumeInbound();
|
|
894
895
|
}
|
|
895
896
|
|
|
896
897
|
if (!step) message.ack();
|
|
@@ -41,9 +41,9 @@ Object.defineProperty(BoundaryEventBehaviour.prototype, 'executionId', {
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
Object.defineProperty(BoundaryEventBehaviour.prototype, 'cancelActivity', {
|
|
44
|
+
/** @returns {boolean} */
|
|
44
45
|
get() {
|
|
45
|
-
|
|
46
|
-
return 'cancelActivity' in behaviour ? behaviour.cancelActivity : true;
|
|
46
|
+
return this.activity.behaviour?.cancelActivity ?? true;
|
|
47
47
|
},
|
|
48
48
|
});
|
|
49
49
|
|
|
@@ -74,13 +74,17 @@ export function ParallelGatewayBehaviour(activity) {
|
|
|
74
74
|
this.type = activity.type;
|
|
75
75
|
this.activity = activity;
|
|
76
76
|
this.broker = activity.broker;
|
|
77
|
+
/**
|
|
78
|
+
* Inbound taken sequence flow sequences
|
|
79
|
+
* @type {Set<import('#types').ElementMessageContent}
|
|
80
|
+
*/
|
|
77
81
|
this.inbound = new Set();
|
|
78
82
|
|
|
79
|
-
this.isConverging = true;
|
|
80
83
|
this[K_EXECUTE_MESSAGE] = undefined;
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
Object.defineProperty(ParallelGatewayBehaviour.prototype, 'executionId', {
|
|
87
|
+
/** @returns {string | undefined} */
|
|
84
88
|
get() {
|
|
85
89
|
return this[K_EXECUTE_MESSAGE]?.content.executionId;
|
|
86
90
|
},
|
|
@@ -112,6 +116,11 @@ ParallelGatewayBehaviour.prototype.execute = function execute(executeMessage) {
|
|
|
112
116
|
}
|
|
113
117
|
};
|
|
114
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Setup peer monitor
|
|
121
|
+
* @param {import('#types').ElementBrokerMessage} executeMessage
|
|
122
|
+
* @returns {void}
|
|
123
|
+
*/
|
|
115
124
|
ParallelGatewayBehaviour.prototype.setup = function setup(executeMessage) {
|
|
116
125
|
const peerIds = new Set([...this.activity[K_PEERS].values()].map((v) => [...v]).flat());
|
|
117
126
|
this[K_TARGETS] = new Map([...peerIds].map((pid) => [pid, this.activity.getActivityById(pid)]));
|
|
@@ -152,9 +161,7 @@ ParallelGatewayBehaviour.prototype.setup = function setup(executeMessage) {
|
|
|
152
161
|
{ consumerTag: '_converging-inbound', exclusive: true, prefetch: 10000 }
|
|
153
162
|
);
|
|
154
163
|
|
|
155
|
-
|
|
156
|
-
this.broker.publish('event', 'activity.converge', cloneContent(executeContent));
|
|
157
|
-
}
|
|
164
|
+
this.broker.publish('event', 'activity.converge', cloneContent(executeContent));
|
|
158
165
|
|
|
159
166
|
return this.broker.publish(
|
|
160
167
|
'execution',
|
|
@@ -197,17 +204,18 @@ ParallelGatewayBehaviour.prototype._stop = function stop() {
|
|
|
197
204
|
this.peerMonitor.stop();
|
|
198
205
|
};
|
|
199
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Peer monitor
|
|
209
|
+
* @param {import('#types').Activity} activity parallel gateway activity
|
|
210
|
+
* @param {Map<string, import('#types').Activity} targets parallel gateway peer target activities
|
|
211
|
+
*/
|
|
200
212
|
function PeerMonitor(activity, targets) {
|
|
201
213
|
this.activity = activity;
|
|
202
214
|
this.id = activity.id;
|
|
203
215
|
this.broker = activity.broker;
|
|
204
|
-
this.running = 0;
|
|
205
|
-
this.index = 0;
|
|
206
|
-
this.discarded = 0;
|
|
207
216
|
this.running = new Map();
|
|
208
217
|
this.watching = new Map();
|
|
209
218
|
this.targets = targets;
|
|
210
|
-
this.touched = new Set();
|
|
211
219
|
this.inbound = [];
|
|
212
220
|
}
|
|
213
221
|
|
|
@@ -217,6 +225,11 @@ Object.defineProperty(PeerMonitor.prototype, 'isRunning', {
|
|
|
217
225
|
},
|
|
218
226
|
});
|
|
219
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Execute peer monitor
|
|
230
|
+
* @param {import('#types').ElementBrokerMessage} executeMessage
|
|
231
|
+
* @returns {number} number of running peers
|
|
232
|
+
*/
|
|
220
233
|
PeerMonitor.prototype.execute = function execute(executeMessage) {
|
|
221
234
|
const message = cloneMessage(executeMessage);
|
|
222
235
|
const inbound = message.content.inbound.pop();
|
|
@@ -231,8 +244,6 @@ PeerMonitor.prototype.execute = function execute(executeMessage) {
|
|
|
231
244
|
preventComplete: true,
|
|
232
245
|
});
|
|
233
246
|
|
|
234
|
-
this.touched.add(inbound.sourceId);
|
|
235
|
-
|
|
236
247
|
for (const target of this.targets.values()) {
|
|
237
248
|
this.monitor(target);
|
|
238
249
|
}
|
|
@@ -240,6 +251,10 @@ PeerMonitor.prototype.execute = function execute(executeMessage) {
|
|
|
240
251
|
return this.running.size;
|
|
241
252
|
};
|
|
242
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Monitor peer activity
|
|
256
|
+
* @param {import('#types').Activity} peerActivity
|
|
257
|
+
*/
|
|
243
258
|
PeerMonitor.prototype.monitor = function monitor(peerActivity) {
|
|
244
259
|
if (this.watching.has(peerActivity.id)) return;
|
|
245
260
|
|
|
@@ -400,7 +400,7 @@ ProcessExecution.prototype._start = function start() {
|
|
|
400
400
|
|
|
401
401
|
for (const a of startActivities) a.init();
|
|
402
402
|
this[K_STATUS] = 'executing';
|
|
403
|
-
for (const a of startActivities) a.
|
|
403
|
+
for (const a of startActivities) a.consumeInbound();
|
|
404
404
|
|
|
405
405
|
if (!startActivities.size) {
|
|
406
406
|
for (const a of this[K_ELEMENTS].triggeredByEvent) {
|
|
@@ -571,7 +571,7 @@ ProcessExecution.prototype._shakeElements = function shakeElements(fromId) {
|
|
|
571
571
|
if (content.parent.id !== this.id) return;
|
|
572
572
|
|
|
573
573
|
switch (routingKey) {
|
|
574
|
-
case 'activity.shake.
|
|
574
|
+
case 'activity.shake.converge': {
|
|
575
575
|
const join = convergingGateways.get(content.join);
|
|
576
576
|
if (!join) {
|
|
577
577
|
convergingGateways.set(content.join, content);
|
package/types/index.d.ts
CHANGED
|
@@ -580,6 +580,11 @@ declare module 'bpmn-elements' {
|
|
|
580
580
|
* Subscribe to inbound flows and start consuming the inbound queue.
|
|
581
581
|
* */
|
|
582
582
|
activate(): void;
|
|
583
|
+
/**
|
|
584
|
+
* Assert the inbound queue consumer when the activity has a trigger or is initialized.
|
|
585
|
+
* Idempotent: asserting the consumer again while one is active is a no-op.
|
|
586
|
+
* */
|
|
587
|
+
consumeInbound(): void;
|
|
583
588
|
/**
|
|
584
589
|
* Cancel inbound subscriptions and any pending run/format consumers.
|
|
585
590
|
*/
|
|
@@ -587,8 +592,9 @@ declare module 'bpmn-elements' {
|
|
|
587
592
|
/**
|
|
588
593
|
* Initialise activity executionId and emit init event without starting the run.
|
|
589
594
|
* @param initContent Optional content merged into the init message
|
|
595
|
+
* @param properties Optional message properties merged into the init message properties
|
|
590
596
|
*/
|
|
591
|
-
init(initContent?: Record<string, any
|
|
597
|
+
init(initContent?: Record<string, any>, properties?: import("smqp").MessageProperties): void;
|
|
592
598
|
/**
|
|
593
599
|
* Start running the activity by publishing run.enter and run.start.
|
|
594
600
|
* @param runContent Optional content merged into the run message
|
|
@@ -1950,7 +1956,7 @@ declare module 'bpmn-elements' {
|
|
|
1950
1956
|
environment: Environment;
|
|
1951
1957
|
broker: ElementBroker<Activity>;
|
|
1952
1958
|
get executionId(): string | undefined;
|
|
1953
|
-
get cancelActivity():
|
|
1959
|
+
get cancelActivity(): boolean;
|
|
1954
1960
|
|
|
1955
1961
|
execute(executeMessage: ElementBrokerMessage): void;
|
|
1956
1962
|
}
|
|
@@ -2106,29 +2112,48 @@ declare module 'bpmn-elements' {
|
|
|
2106
2112
|
type: string;
|
|
2107
2113
|
activity: Activity;
|
|
2108
2114
|
broker: ElementBroker<Activity>;
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2115
|
+
/**
|
|
2116
|
+
* Inbound taken sequence flow sequences
|
|
2117
|
+
* */
|
|
2118
|
+
inbound: Set<ElementMessageContent>;
|
|
2119
|
+
get executionId(): string | undefined;
|
|
2112
2120
|
|
|
2113
2121
|
execute(executeMessage: ElementBrokerMessage): void;
|
|
2114
|
-
|
|
2122
|
+
/**
|
|
2123
|
+
* Setup peer monitor
|
|
2124
|
+
* */
|
|
2125
|
+
setup(executeMessage: ElementBrokerMessage): void;
|
|
2115
2126
|
peerMonitor: PeerMonitor | undefined;
|
|
2116
2127
|
}
|
|
2128
|
+
/**
|
|
2129
|
+
* Peer monitor
|
|
2130
|
+
* @param activity parallel gateway activity
|
|
2131
|
+
* @param targets parallel gateway peer target activities
|
|
2132
|
+
*/
|
|
2117
2133
|
class PeerMonitor {
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2134
|
+
/**
|
|
2135
|
+
* Peer monitor
|
|
2136
|
+
* @param activity parallel gateway activity
|
|
2137
|
+
* @param targets parallel gateway peer target activities
|
|
2138
|
+
*/
|
|
2139
|
+
constructor(activity: Activity, targets: Map<string, Activity>);
|
|
2140
|
+
activity: Activity;
|
|
2141
|
+
id: string | undefined;
|
|
2142
|
+
broker: ElementBroker<Activity>;
|
|
2122
2143
|
running: Map<any, any>;
|
|
2123
|
-
index: number;
|
|
2124
|
-
discarded: number;
|
|
2125
2144
|
watching: Map<any, any>;
|
|
2126
|
-
targets:
|
|
2127
|
-
touched: Set<any>;
|
|
2145
|
+
targets: Map<string, Activity>;
|
|
2128
2146
|
inbound: any[];
|
|
2129
2147
|
get isRunning(): boolean;
|
|
2130
|
-
|
|
2131
|
-
|
|
2148
|
+
/**
|
|
2149
|
+
* Execute peer monitor
|
|
2150
|
+
* @returns number of running peers
|
|
2151
|
+
*/
|
|
2152
|
+
execute(executeMessage: ElementBrokerMessage): number;
|
|
2153
|
+
/**
|
|
2154
|
+
* Monitor peer activity
|
|
2155
|
+
* */
|
|
2156
|
+
monitor(peerActivity: Activity): void;
|
|
2132
2157
|
stop(): void;
|
|
2133
2158
|
}
|
|
2134
2159
|
/**
|