bpmn-elements 18.0.1 → 18.0.3
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/Process.js +36 -5
- 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/Process.js +36 -4
- package/src/process/ProcessExecution.js +2 -2
- package/types/index.d.ts +44 -16
- package/types/interfaces.d.ts +2 -0
|
@@ -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}`);
|
package/dist/process/Process.js
CHANGED
|
@@ -8,10 +8,12 @@ var _ProcessExecution = require("./ProcessExecution.js");
|
|
|
8
8
|
var _shared = require("../shared.js");
|
|
9
9
|
var _Api = require("../Api.js");
|
|
10
10
|
var _EventBroker = require("../EventBroker.js");
|
|
11
|
+
var _MessageFormatter = require("../MessageFormatter.js");
|
|
11
12
|
var _messageHelper = require("../messageHelper.js");
|
|
12
13
|
var _Errors = require("../error/Errors.js");
|
|
13
14
|
var _constants = require("../constants.js");
|
|
14
15
|
const K_LANES = Symbol.for('lanes');
|
|
16
|
+
const K_FORMATTER = Symbol.for('formatter');
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* Owns one `<bpmn:process>`. Wraps the structural definition and orchestrates flow traversal,
|
|
@@ -49,12 +51,14 @@ function Process(processDef, context) {
|
|
|
49
51
|
broker,
|
|
50
52
|
on,
|
|
51
53
|
once,
|
|
52
|
-
waitFor
|
|
54
|
+
waitFor,
|
|
55
|
+
emitFatal
|
|
53
56
|
} = (0, _EventBroker.ProcessBroker)(this);
|
|
54
57
|
this.broker = broker;
|
|
55
58
|
this.on = on;
|
|
56
59
|
this.once = once;
|
|
57
60
|
this.waitFor = waitFor;
|
|
61
|
+
this.emitFatal = emitFatal;
|
|
58
62
|
this[_constants.K_MESSAGE_HANDLERS] = {
|
|
59
63
|
onApiMessage: this._onApiMessage.bind(this),
|
|
60
64
|
onRunMessage: this._onRunMessage.bind(this),
|
|
@@ -84,6 +88,14 @@ Object.defineProperties(Process.prototype, {
|
|
|
84
88
|
return this[_constants.K_EXTENSIONS];
|
|
85
89
|
}
|
|
86
90
|
},
|
|
91
|
+
formatter: {
|
|
92
|
+
get() {
|
|
93
|
+
let formatter = this[K_FORMATTER];
|
|
94
|
+
if (formatter) return formatter;
|
|
95
|
+
formatter = this[K_FORMATTER] = new _MessageFormatter.Formatter(this);
|
|
96
|
+
return formatter;
|
|
97
|
+
}
|
|
98
|
+
},
|
|
87
99
|
stopped: {
|
|
88
100
|
get() {
|
|
89
101
|
return this[_constants.K_STOPPED];
|
|
@@ -292,14 +304,28 @@ Process.prototype._deactivateRunConsumers = function deactivateRunConsumers() {
|
|
|
292
304
|
};
|
|
293
305
|
|
|
294
306
|
/** @internal */
|
|
295
|
-
Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
307
|
+
Process.prototype._onRunMessage = function onRunMessage(routingKey, message, messageProperties) {
|
|
308
|
+
if (routingKey === 'run.resume') {
|
|
309
|
+
return this._onResumeMessage(message);
|
|
310
|
+
}
|
|
311
|
+
const preStatus = this[_constants.K_STATUS];
|
|
312
|
+
this[_constants.K_STATUS] = 'formatting';
|
|
313
|
+
return this.formatter.format(message, (err, formattedContent, formatted) => {
|
|
314
|
+
this[_constants.K_STATUS] = preStatus;
|
|
315
|
+
if (err) {
|
|
316
|
+
return this.emitFatal(err, message.content);
|
|
317
|
+
}
|
|
318
|
+
if (formatted) message.content = formattedContent;
|
|
319
|
+
this._continueRunMessage(routingKey, message, messageProperties);
|
|
320
|
+
});
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
/** @internal */
|
|
324
|
+
Process.prototype._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
296
325
|
const {
|
|
297
326
|
content,
|
|
298
327
|
fields
|
|
299
328
|
} = message;
|
|
300
|
-
if (routingKey === 'run.resume') {
|
|
301
|
-
return this._onResumeMessage(message);
|
|
302
|
-
}
|
|
303
329
|
this[_constants.K_STATE_MESSAGE] = message;
|
|
304
330
|
switch (routingKey) {
|
|
305
331
|
case 'run.enter':
|
|
@@ -308,6 +334,7 @@ Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
|
308
334
|
this[_constants.K_STATUS] = 'entered';
|
|
309
335
|
if (fields.redelivered) break;
|
|
310
336
|
this[_constants.K_EXECUTION].delete('execution');
|
|
337
|
+
if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
|
|
311
338
|
this._publishEvent('enter', content);
|
|
312
339
|
break;
|
|
313
340
|
}
|
|
@@ -322,6 +349,7 @@ Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
|
322
349
|
{
|
|
323
350
|
const exec = this[_constants.K_EXECUTION];
|
|
324
351
|
this[_constants.K_STATUS] = 'executing';
|
|
352
|
+
if (fields.redelivered && this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(message));
|
|
325
353
|
const executeMessage = (0, _messageHelper.cloneMessage)(message);
|
|
326
354
|
let execution = exec.get('execution');
|
|
327
355
|
if (fields.redelivered && !execution) {
|
|
@@ -366,6 +394,7 @@ Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
|
366
394
|
case 'run.leave':
|
|
367
395
|
{
|
|
368
396
|
this[_constants.K_STATUS] = undefined;
|
|
397
|
+
if (this.extensions) this.extensions.deactivate((0, _messageHelper.cloneMessage)(message));
|
|
369
398
|
message.ack();
|
|
370
399
|
this._deactivateRunConsumers();
|
|
371
400
|
const {
|
|
@@ -394,6 +423,7 @@ Process.prototype._onResumeMessage = function onResumeMessage(message) {
|
|
|
394
423
|
return;
|
|
395
424
|
}
|
|
396
425
|
if (!stateMessage.fields.redelivered) return;
|
|
426
|
+
if (this.extensions) this.extensions.activate((0, _messageHelper.cloneMessage)(stateMessage));
|
|
397
427
|
this._debug(`resume from ${this.status}`);
|
|
398
428
|
return this.broker.publish('run', stateMessage.fields.routingKey, (0, _messageHelper.cloneContent)(stateMessage.content), stateMessage.properties);
|
|
399
429
|
};
|
|
@@ -530,6 +560,7 @@ Process.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
|
530
560
|
Process.prototype._onStop = function onStop() {
|
|
531
561
|
this[_constants.K_STOPPED] = true;
|
|
532
562
|
this._deactivateRunConsumers();
|
|
563
|
+
if (this.extensions) this.extensions.deactivate((0, _messageHelper.cloneMessage)(this[_constants.K_STATE_MESSAGE]));
|
|
533
564
|
return this._publishEvent('stop');
|
|
534
565
|
};
|
|
535
566
|
|
|
@@ -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
|
|
package/src/process/Process.js
CHANGED
|
@@ -2,6 +2,7 @@ import { ProcessExecution } from './ProcessExecution.js';
|
|
|
2
2
|
import { getUniqueId } from '../shared.js';
|
|
3
3
|
import { ProcessApi } from '../Api.js';
|
|
4
4
|
import { ProcessBroker } from '../EventBroker.js';
|
|
5
|
+
import { Formatter } from '../MessageFormatter.js';
|
|
5
6
|
import { cloneMessage, cloneContent, cloneParent } from '../messageHelper.js';
|
|
6
7
|
import { makeErrorFromMessage } from '../error/Errors.js';
|
|
7
8
|
import {
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
} from '../constants.js';
|
|
18
19
|
|
|
19
20
|
const K_LANES = Symbol.for('lanes');
|
|
21
|
+
const K_FORMATTER = Symbol.for('formatter');
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* Owns one `<bpmn:process>`. Wraps the structural definition and orchestrates flow traversal,
|
|
@@ -47,11 +49,12 @@ export function Process(processDef, context) {
|
|
|
47
49
|
this[K_STATUS] = undefined;
|
|
48
50
|
this[K_STOPPED] = false;
|
|
49
51
|
|
|
50
|
-
const { broker, on, once, waitFor } = ProcessBroker(this);
|
|
52
|
+
const { broker, on, once, waitFor, emitFatal } = ProcessBroker(this);
|
|
51
53
|
this.broker = broker;
|
|
52
54
|
this.on = on;
|
|
53
55
|
this.once = once;
|
|
54
56
|
this.waitFor = waitFor;
|
|
57
|
+
this.emitFatal = emitFatal;
|
|
55
58
|
|
|
56
59
|
this[K_MESSAGE_HANDLERS] = {
|
|
57
60
|
onApiMessage: this._onApiMessage.bind(this),
|
|
@@ -83,6 +86,14 @@ Object.defineProperties(Process.prototype, {
|
|
|
83
86
|
return this[K_EXTENSIONS];
|
|
84
87
|
},
|
|
85
88
|
},
|
|
89
|
+
formatter: {
|
|
90
|
+
get() {
|
|
91
|
+
let formatter = this[K_FORMATTER];
|
|
92
|
+
if (formatter) return formatter;
|
|
93
|
+
formatter = this[K_FORMATTER] = new Formatter(this);
|
|
94
|
+
return formatter;
|
|
95
|
+
},
|
|
96
|
+
},
|
|
86
97
|
stopped: {
|
|
87
98
|
get() {
|
|
88
99
|
return this[K_STOPPED];
|
|
@@ -278,13 +289,28 @@ Process.prototype._deactivateRunConsumers = function deactivateRunConsumers() {
|
|
|
278
289
|
};
|
|
279
290
|
|
|
280
291
|
/** @internal */
|
|
281
|
-
Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
282
|
-
const { content, fields } = message;
|
|
283
|
-
|
|
292
|
+
Process.prototype._onRunMessage = function onRunMessage(routingKey, message, messageProperties) {
|
|
284
293
|
if (routingKey === 'run.resume') {
|
|
285
294
|
return this._onResumeMessage(message);
|
|
286
295
|
}
|
|
287
296
|
|
|
297
|
+
const preStatus = this[K_STATUS];
|
|
298
|
+
this[K_STATUS] = 'formatting';
|
|
299
|
+
|
|
300
|
+
return this.formatter.format(message, (err, formattedContent, formatted) => {
|
|
301
|
+
this[K_STATUS] = preStatus;
|
|
302
|
+
if (err) {
|
|
303
|
+
return this.emitFatal(err, message.content);
|
|
304
|
+
}
|
|
305
|
+
if (formatted) message.content = formattedContent;
|
|
306
|
+
this._continueRunMessage(routingKey, message, messageProperties);
|
|
307
|
+
});
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
/** @internal */
|
|
311
|
+
Process.prototype._continueRunMessage = function continueRunMessage(routingKey, message) {
|
|
312
|
+
const { content, fields } = message;
|
|
313
|
+
|
|
288
314
|
this[K_STATE_MESSAGE] = message;
|
|
289
315
|
|
|
290
316
|
switch (routingKey) {
|
|
@@ -295,6 +321,7 @@ Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
|
295
321
|
if (fields.redelivered) break;
|
|
296
322
|
|
|
297
323
|
this[K_EXECUTION].delete('execution');
|
|
324
|
+
if (this.extensions) this.extensions.activate(cloneMessage(message));
|
|
298
325
|
this._publishEvent('enter', content);
|
|
299
326
|
|
|
300
327
|
break;
|
|
@@ -308,6 +335,7 @@ Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
|
308
335
|
case 'run.execute': {
|
|
309
336
|
const exec = this[K_EXECUTION];
|
|
310
337
|
this[K_STATUS] = 'executing';
|
|
338
|
+
if (fields.redelivered && this.extensions) this.extensions.activate(cloneMessage(message));
|
|
311
339
|
const executeMessage = cloneMessage(message);
|
|
312
340
|
let execution = exec.get('execution');
|
|
313
341
|
if (fields.redelivered && !execution) {
|
|
@@ -360,6 +388,7 @@ Process.prototype._onRunMessage = function onRunMessage(routingKey, message) {
|
|
|
360
388
|
}
|
|
361
389
|
case 'run.leave': {
|
|
362
390
|
this[K_STATUS] = undefined;
|
|
391
|
+
if (this.extensions) this.extensions.deactivate(cloneMessage(message));
|
|
363
392
|
message.ack();
|
|
364
393
|
this._deactivateRunConsumers();
|
|
365
394
|
const { output, ...rest } = content;
|
|
@@ -389,6 +418,8 @@ Process.prototype._onResumeMessage = function onResumeMessage(message) {
|
|
|
389
418
|
|
|
390
419
|
if (!stateMessage.fields.redelivered) return;
|
|
391
420
|
|
|
421
|
+
if (this.extensions) this.extensions.activate(cloneMessage(stateMessage));
|
|
422
|
+
|
|
392
423
|
this._debug(`resume from ${this.status}`);
|
|
393
424
|
|
|
394
425
|
return this.broker.publish('run', stateMessage.fields.routingKey, cloneContent(stateMessage.content), stateMessage.properties);
|
|
@@ -518,6 +549,7 @@ Process.prototype._onApiMessage = function onApiMessage(routingKey, message) {
|
|
|
518
549
|
Process.prototype._onStop = function onStop() {
|
|
519
550
|
this[K_STOPPED] = true;
|
|
520
551
|
this._deactivateRunConsumers();
|
|
552
|
+
if (this.extensions) this.extensions.deactivate(cloneMessage(this[K_STATE_MESSAGE]));
|
|
521
553
|
return this._publishEvent('stop');
|
|
522
554
|
};
|
|
523
555
|
|
|
@@ -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
|
@@ -261,6 +261,8 @@ declare module 'bpmn-elements' {
|
|
|
261
261
|
export enum ProcessStatusValue {
|
|
262
262
|
/** ProcessExecution constructed, not yet started */
|
|
263
263
|
Init = 'init',
|
|
264
|
+
/** Formatting next run message */
|
|
265
|
+
Formatting = 'formatting',
|
|
264
266
|
/** Process run entered */
|
|
265
267
|
Entered = 'entered',
|
|
266
268
|
/** Process run started */
|
|
@@ -580,6 +582,11 @@ declare module 'bpmn-elements' {
|
|
|
580
582
|
* Subscribe to inbound flows and start consuming the inbound queue.
|
|
581
583
|
* */
|
|
582
584
|
activate(): void;
|
|
585
|
+
/**
|
|
586
|
+
* Assert the inbound queue consumer when the activity has a trigger or is initialized.
|
|
587
|
+
* Idempotent: asserting the consumer again while one is active is a no-op.
|
|
588
|
+
* */
|
|
589
|
+
consumeInbound(): void;
|
|
583
590
|
/**
|
|
584
591
|
* Cancel inbound subscriptions and any pending run/format consumers.
|
|
585
592
|
*/
|
|
@@ -587,8 +594,9 @@ declare module 'bpmn-elements' {
|
|
|
587
594
|
/**
|
|
588
595
|
* Initialise activity executionId and emit init event without starting the run.
|
|
589
596
|
* @param initContent Optional content merged into the init message
|
|
597
|
+
* @param properties Optional message properties merged into the init message properties
|
|
590
598
|
*/
|
|
591
|
-
init(initContent?: Record<string, any
|
|
599
|
+
init(initContent?: Record<string, any>, properties?: import("smqp").MessageProperties): void;
|
|
592
600
|
/**
|
|
593
601
|
* Start running the activity by publishing run.enter and run.start.
|
|
594
602
|
* @param runContent Optional content merged into the run message
|
|
@@ -1452,6 +1460,7 @@ declare module 'bpmn-elements' {
|
|
|
1452
1460
|
[x: string]: any;
|
|
1453
1461
|
}) => import("smqp").Consumer;
|
|
1454
1462
|
waitFor: (eventName: string, onMessage?: ((routingKey: string, message: ElementBrokerMessage, owner: Process) => boolean) | undefined) => Promise<IApi<Process>>;
|
|
1463
|
+
emitFatal: (error: Error, content?: Record<string, any>) => void;
|
|
1455
1464
|
logger: ILogger;
|
|
1456
1465
|
/**
|
|
1457
1466
|
* Allocate an executionId and emit init event without starting the run.
|
|
@@ -1950,7 +1959,7 @@ declare module 'bpmn-elements' {
|
|
|
1950
1959
|
environment: Environment;
|
|
1951
1960
|
broker: ElementBroker<Activity>;
|
|
1952
1961
|
get executionId(): string | undefined;
|
|
1953
|
-
get cancelActivity():
|
|
1962
|
+
get cancelActivity(): boolean;
|
|
1954
1963
|
|
|
1955
1964
|
execute(executeMessage: ElementBrokerMessage): void;
|
|
1956
1965
|
}
|
|
@@ -2106,29 +2115,48 @@ declare module 'bpmn-elements' {
|
|
|
2106
2115
|
type: string;
|
|
2107
2116
|
activity: Activity;
|
|
2108
2117
|
broker: ElementBroker<Activity>;
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2118
|
+
/**
|
|
2119
|
+
* Inbound taken sequence flow sequences
|
|
2120
|
+
* */
|
|
2121
|
+
inbound: Set<ElementMessageContent>;
|
|
2122
|
+
get executionId(): string | undefined;
|
|
2112
2123
|
|
|
2113
2124
|
execute(executeMessage: ElementBrokerMessage): void;
|
|
2114
|
-
|
|
2125
|
+
/**
|
|
2126
|
+
* Setup peer monitor
|
|
2127
|
+
* */
|
|
2128
|
+
setup(executeMessage: ElementBrokerMessage): void;
|
|
2115
2129
|
peerMonitor: PeerMonitor | undefined;
|
|
2116
2130
|
}
|
|
2131
|
+
/**
|
|
2132
|
+
* Peer monitor
|
|
2133
|
+
* @param activity parallel gateway activity
|
|
2134
|
+
* @param targets parallel gateway peer target activities
|
|
2135
|
+
*/
|
|
2117
2136
|
class PeerMonitor {
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2137
|
+
/**
|
|
2138
|
+
* Peer monitor
|
|
2139
|
+
* @param activity parallel gateway activity
|
|
2140
|
+
* @param targets parallel gateway peer target activities
|
|
2141
|
+
*/
|
|
2142
|
+
constructor(activity: Activity, targets: Map<string, Activity>);
|
|
2143
|
+
activity: Activity;
|
|
2144
|
+
id: string | undefined;
|
|
2145
|
+
broker: ElementBroker<Activity>;
|
|
2122
2146
|
running: Map<any, any>;
|
|
2123
|
-
index: number;
|
|
2124
|
-
discarded: number;
|
|
2125
2147
|
watching: Map<any, any>;
|
|
2126
|
-
targets:
|
|
2127
|
-
touched: Set<any>;
|
|
2148
|
+
targets: Map<string, Activity>;
|
|
2128
2149
|
inbound: any[];
|
|
2129
2150
|
get isRunning(): boolean;
|
|
2130
|
-
|
|
2131
|
-
|
|
2151
|
+
/**
|
|
2152
|
+
* Execute peer monitor
|
|
2153
|
+
* @returns number of running peers
|
|
2154
|
+
*/
|
|
2155
|
+
execute(executeMessage: ElementBrokerMessage): number;
|
|
2156
|
+
/**
|
|
2157
|
+
* Monitor peer activity
|
|
2158
|
+
* */
|
|
2159
|
+
monitor(peerActivity: Activity): void;
|
|
2132
2160
|
stop(): void;
|
|
2133
2161
|
}
|
|
2134
2162
|
/**
|
package/types/interfaces.d.ts
CHANGED
|
@@ -359,6 +359,8 @@ export type DefinitionStatus = DefinitionStatusValue | `${DefinitionStatusValue}
|
|
|
359
359
|
export const enum ProcessStatusValue {
|
|
360
360
|
/** ProcessExecution constructed, not yet started */
|
|
361
361
|
Init = 'init',
|
|
362
|
+
/** Formatting next run message */
|
|
363
|
+
Formatting = 'formatting',
|
|
362
364
|
/** Process run entered */
|
|
363
365
|
Entered = 'entered',
|
|
364
366
|
/** Process run started */
|