bpmn-elements 9.0.0 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/dist/EventBroker.js +4 -0
  4. package/dist/Tracker.js +89 -0
  5. package/dist/activity/Activity.js +47 -57
  6. package/dist/activity/ActivityExecution.js +6 -9
  7. package/dist/definition/Definition.js +23 -17
  8. package/dist/definition/DefinitionExecution.js +23 -0
  9. package/dist/eventDefinitions/CancelEventDefinition.js +20 -76
  10. package/dist/eventDefinitions/CompensateEventDefinition.js +54 -41
  11. package/dist/eventDefinitions/ConditionalEventDefinition.js +11 -2
  12. package/dist/eventDefinitions/ErrorEventDefinition.js +2 -0
  13. package/dist/events/BoundaryEvent.js +25 -10
  14. package/dist/flows/Association.js +0 -7
  15. package/dist/gateways/EventBasedGateway.js +1 -2
  16. package/dist/process/Process.js +5 -0
  17. package/dist/process/ProcessExecution.js +128 -36
  18. package/dist/tasks/SubProcess.js +2 -1
  19. package/package.json +4 -4
  20. package/src/EventBroker.js +1 -0
  21. package/src/Tracker.js +73 -0
  22. package/src/activity/Activity.js +45 -51
  23. package/src/activity/ActivityExecution.js +6 -8
  24. package/src/definition/Definition.js +24 -21
  25. package/src/definition/DefinitionExecution.js +26 -0
  26. package/src/eventDefinitions/CancelEventDefinition.js +22 -66
  27. package/src/eventDefinitions/CompensateEventDefinition.js +48 -40
  28. package/src/eventDefinitions/ConditionalEventDefinition.js +12 -2
  29. package/src/eventDefinitions/ErrorEventDefinition.js +2 -0
  30. package/src/events/BoundaryEvent.js +20 -8
  31. package/src/flows/Association.js +0 -10
  32. package/src/gateways/EventBasedGateway.js +1 -2
  33. package/src/process/Process.js +6 -0
  34. package/src/process/ProcessExecution.js +126 -36
  35. package/src/tasks/SubProcess.js +2 -1
  36. package/types/index.d.ts +29 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,12 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ # 9.1.0
5
+
6
+ - refactor compensation and transaction functionality
7
+ - fix event based gateway bug when/if a subsequent event completes immediately
8
+ - add somewhat expirimental activityStatus property to process and definition, tracked by Tracker that tracks executing, wait, and timer activity
9
+
4
10
  # 9.0.0
5
11
 
6
12
  - Turn into module with exports for node
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  bpmn-elements
2
2
  =============
3
3
 
4
- [![Build Status](https://app.travis-ci.com/paed01/bpmn-elements.svg?branch=master)](https://app.travis-ci.com/paed01/bpmn-elements)[![Coverage Status](https://coveralls.io/repos/github/paed01/bpmn-elements/badge.svg?branch=master)](https://coveralls.io/github/paed01/bpmn-elements?branch=master)
4
+ [![Build](https://github.com/paed01/bpmn-elements/actions/workflows/build.yaml/badge.svg)](https://github.com/paed01/bpmn-elements/actions/workflows/build.yaml)[![Coverage Status](https://coveralls.io/repos/github/paed01/bpmn-elements/badge.svg?branch=master)](https://coveralls.io/github/paed01/bpmn-elements?branch=master)
5
5
 
6
6
  Isomorphic JavaScript BPMN 2.0 workflow elements suitable for bundling into frontend script or just required into your nodejs project.
7
7
 
@@ -76,6 +76,10 @@ function ExecutionBroker(brokerOwner, prefix, onBrokerReturn) {
76
76
  durable: true,
77
77
  autoDelete: false
78
78
  });
79
+ broker.assertQueue('inbound-q', {
80
+ durable: true,
81
+ autoDelete: false
82
+ });
79
83
  broker.bindQueue(runQ.name, 'run', 'run.#');
80
84
  broker.bindQueue(formatRunQ.name, 'format', 'run.#');
81
85
  broker.bindQueue(executionQ.name, 'execution', 'execution.#');
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ActivityTracker = ActivityTracker;
7
+ function ActivityTracker(parentId) {
8
+ this.id = parentId;
9
+ this.status = {
10
+ wait: [],
11
+ execute: [],
12
+ timer: []
13
+ };
14
+ }
15
+ Object.defineProperty(ActivityTracker.prototype, 'activityStatus', {
16
+ get() {
17
+ const status = this.status;
18
+ if (status.execute.length) return 'executing';
19
+ if (status.timer.length) return 'timer';
20
+ return status.wait.length ? 'wait' : 'idle';
21
+ }
22
+ });
23
+ ActivityTracker.prototype.track = function track(routingKey, message) {
24
+ const content = message.content;
25
+ if (content.isSequenceFlow) return;
26
+ if (content.isSubProcess) return;
27
+ const executionId = content.executionId;
28
+ switch (routingKey) {
29
+ case 'activity.enter':
30
+ case 'activity.discard':
31
+ case 'activity.start':
32
+ case 'activity.execution.completed':
33
+ case 'activity.execution.error':
34
+ case 'activity.end':
35
+ this._executing(executionId);
36
+ break;
37
+ case 'activity.execution.outbound.take':
38
+ case 'activity.detach':
39
+ case 'activity.wait':
40
+ {
41
+ if (content.isMultiInstance) this._waiting(content.parent.executionId);else this._waiting(executionId);
42
+ break;
43
+ }
44
+ case 'activity.timer':
45
+ this._timer(content.parent.executionId);
46
+ break;
47
+ case 'activity.leave':
48
+ this._leave(executionId);
49
+ break;
50
+ }
51
+ };
52
+ ActivityTracker.prototype._executing = function executing(id) {
53
+ const {
54
+ wait,
55
+ execute
56
+ } = this.status;
57
+ if (execute.indexOf(id) === -1) execute.push(id);
58
+ let idx;
59
+ if ((idx = wait.indexOf(id)) !== -1) wait.splice(idx, 1);
60
+ };
61
+ ActivityTracker.prototype._waiting = function waiting(id) {
62
+ const {
63
+ wait,
64
+ execute
65
+ } = this.status;
66
+ if (wait.indexOf(id) === -1) wait.push(id);
67
+ let idx;
68
+ if ((idx = execute.indexOf(id)) !== -1) execute.splice(idx, 1);
69
+ };
70
+ ActivityTracker.prototype._timer = function timerFn(id) {
71
+ const {
72
+ timer,
73
+ execute
74
+ } = this.status;
75
+ if (timer.indexOf(id) === -1) timer.push(id);
76
+ let idx;
77
+ if ((idx = execute.indexOf(id)) !== -1) execute.splice(idx, 1);
78
+ };
79
+ ActivityTracker.prototype._leave = function leave(id) {
80
+ const {
81
+ wait,
82
+ execute,
83
+ timer
84
+ } = this.status;
85
+ let idx;
86
+ if ((idx = wait.indexOf(id)) !== -1) wait.splice(idx, 1);
87
+ if ((idx = execute.indexOf(id)) !== -1) execute.splice(idx, 1);
88
+ if ((idx = timer.indexOf(id)) !== -1) timer.splice(idx, 1);
89
+ };
@@ -24,6 +24,7 @@ const kFlows = Symbol.for('flows');
24
24
  const kFormatter = Symbol.for('formatter');
25
25
  const kMessageHandlers = Symbol.for('messageHandlers');
26
26
  const kStateMessage = Symbol.for('stateMessage');
27
+ const kActivated = Symbol.for('activated');
27
28
  var _default = Activity;
28
29
  exports.default = _default;
29
30
  function Activity(Behaviour, activityDef, context) {
@@ -54,6 +55,7 @@ function Activity(Behaviour, activityDef, context) {
54
55
  taken: 0,
55
56
  discarded: 0
56
57
  };
58
+ const isForCompensation = !!behaviour.isForCompensation;
57
59
  let attachedToActivity, attachedTo;
58
60
  if (attachedToRef) {
59
61
  attachedTo = attachedToRef.id;
@@ -73,7 +75,14 @@ function Activity(Behaviour, activityDef, context) {
73
75
  this.emitFatal = emitFatal;
74
76
  const inboundSequenceFlows = context.getInboundSequenceFlows(id);
75
77
  const inboundAssociations = context.getInboundAssociations(id);
76
- const inboundTriggers = attachedToActivity ? [attachedToActivity] : inboundSequenceFlows.slice();
78
+ let inboundTriggers;
79
+ if (attachedToActivity) {
80
+ inboundTriggers = [attachedToActivity];
81
+ } else if (isForCompensation) {
82
+ inboundTriggers = inboundAssociations.slice();
83
+ } else {
84
+ inboundTriggers = inboundSequenceFlows.slice();
85
+ }
77
86
  const outboundSequenceFlows = context.getOutboundSequenceFlows(id);
78
87
  const flows = this[kFlows] = {
79
88
  inboundSequenceFlows,
@@ -83,7 +92,6 @@ function Activity(Behaviour, activityDef, context) {
83
92
  outboundSequenceFlows,
84
93
  outboundEvaluator: new OutboundEvaluator(this, outboundSequenceFlows)
85
94
  };
86
- const isForCompensation = !!behaviour.isForCompensation;
87
95
  const isParallelJoin = activityDef.isParallelGateway && flows.inboundSequenceFlows.length > 1;
88
96
  this[kFlags] = {
89
97
  isEnd: flows.outboundSequenceFlows.length === 0,
@@ -103,29 +111,6 @@ function Activity(Behaviour, activityDef, context) {
103
111
  onApiMessage: this._onApiMessage.bind(this),
104
112
  onExecutionMessage: this._onExecutionMessage.bind(this)
105
113
  };
106
- const onInboundEvent = this._onInboundEvent.bind(this);
107
- broker.assertQueue('inbound-q', {
108
- durable: true,
109
- autoDelete: false
110
- });
111
- if (isForCompensation) {
112
- for (const trigger of inboundAssociations) {
113
- trigger.broker.subscribeTmp('event', '#', onInboundEvent, {
114
- noAck: true,
115
- consumerTag: `_inbound-${id}`
116
- });
117
- }
118
- } else {
119
- for (const trigger of inboundTriggers) {
120
- if (trigger.isSequenceFlow) trigger.broker.subscribeTmp('event', 'flow.#', onInboundEvent, {
121
- noAck: true,
122
- consumerTag: `_inbound-${id}`
123
- });else trigger.broker.subscribeTmp('event', 'activity.#', onInboundEvent, {
124
- noAck: true,
125
- consumerTag: `_inbound-${id}`
126
- });
127
- }
128
- }
129
114
  this[kEventDefinitions] = eventDefinitions && eventDefinitions.map(ed => new ed.Behaviour(this, ed, this.context));
130
115
  this[kExtensions] = context.loadExtensions(this);
131
116
  }
@@ -213,6 +198,12 @@ Object.defineProperty(Activity.prototype, 'isSubProcess', {
213
198
  return this[kFlags].isSubProcess;
214
199
  }
215
200
  });
201
+ Object.defineProperty(Activity.prototype, 'isTransaction', {
202
+ enumerable: true,
203
+ get() {
204
+ return this[kFlags].isTransaction;
205
+ }
206
+ });
216
207
  Object.defineProperty(Activity.prototype, 'isMultiInstance', {
217
208
  enumerable: true,
218
209
  get() {
@@ -252,11 +243,14 @@ Object.defineProperty(Activity.prototype, 'eventDefinitions', {
252
243
  }
253
244
  });
254
245
  Activity.prototype.activate = function activate() {
255
- if (this[kFlags].isForCompensation) return;
246
+ this[kActivated] = true;
247
+ this.addInboundListeners();
256
248
  return this._consumeInbound();
257
249
  };
258
250
  Activity.prototype.deactivate = function deactivate() {
251
+ this[kActivated] = false;
259
252
  const broker = this.broker;
253
+ this.removeInboundListeners();
260
254
  broker.cancel('_run-on-inbound');
261
255
  broker.cancel('_format-consumer');
262
256
  };
@@ -326,9 +320,31 @@ Activity.prototype.discard = function discard(discardContent) {
326
320
  broker.publish('run', 'run.discard', (0, _messageHelper.cloneContent)(this[kStateMessage].content));
327
321
  this._consumeRunQ();
328
322
  };
323
+ Activity.prototype.addInboundListeners = function addInboundListeners() {
324
+ const onInboundEvent = this._onInboundEvent.bind(this);
325
+ const triggerConsumerTag = `_inbound-${this.id}`;
326
+ for (const trigger of this[kFlows].inboundTriggers) {
327
+ if (trigger.isSequenceFlow) trigger.broker.subscribeTmp('event', 'flow.#', onInboundEvent, {
328
+ noAck: true,
329
+ consumerTag: triggerConsumerTag
330
+ });else if (this.isForCompensation) trigger.broker.subscribeTmp('event', 'association.#', onInboundEvent, {
331
+ noAck: true,
332
+ consumerTag: triggerConsumerTag
333
+ });else trigger.broker.subscribeTmp('event', 'activity.#', onInboundEvent, {
334
+ noAck: true,
335
+ consumerTag: triggerConsumerTag
336
+ });
337
+ }
338
+ };
339
+ Activity.prototype.removeInboundListeners = function removeInboundListeners() {
340
+ const triggerConsumerTag = `_inbound-${this.id}`;
341
+ for (const trigger of this[kFlows].inboundTriggers) {
342
+ trigger.broker.cancel(triggerConsumerTag);
343
+ }
344
+ };
329
345
  Activity.prototype.stop = function stop() {
330
- if (!this[kConsuming]) return;
331
- return this.getApi().stop();
346
+ if (!this[kConsuming]) return this.broker.cancel('_run-on-inbound');
347
+ return this.getApi(this[kStateMessage]).stop();
332
348
  };
333
349
  Activity.prototype.next = function next() {
334
350
  if (!this.environment.settings.step) return;
@@ -423,6 +439,7 @@ Activity.prototype._shakeOutbound = function shakeOutbound(sourceMessage) {
423
439
  for (const flow of this[kFlows].outboundSequenceFlows) flow.shake(message);
424
440
  };
425
441
  Activity.prototype._consumeInbound = function consumeInbound() {
442
+ if (!this[kActivated]) return;
426
443
  if (this.status) return;
427
444
  const inboundQ = this.broker.getQueue('inbound-q');
428
445
  if (this[kFlags].isParallelJoin) {
@@ -437,7 +454,6 @@ Activity.prototype._consumeInbound = function consumeInbound() {
437
454
  };
438
455
  Activity.prototype._onInbound = function onInbound(routingKey, message) {
439
456
  message.ack();
440
- const id = this.id;
441
457
  const broker = this.broker;
442
458
  broker.cancel('_run-on-inbound');
443
459
  const content = message.content;
@@ -461,15 +477,6 @@ Activity.prototype._onInbound = function onInbound(routingKey, message) {
461
477
  discardSequence
462
478
  });
463
479
  }
464
- case 'association.complete':
465
- {
466
- broker.cancel('_run-on-inbound');
467
- const compensationId = `${(0, _shared.brokerSafeId)(id)}_${(0, _shared.brokerSafeId)(content.sequenceId)}`;
468
- this.logger.debug(`<${id}> completed compensation with id <${compensationId}>`);
469
- return this._publishEvent('compensation.end', this._createMessage({
470
- executionId: compensationId
471
- }));
472
- }
473
480
  }
474
481
  };
475
482
  Activity.prototype._onJoinInbound = function onJoinInbound(routingKey, message) {
@@ -521,7 +528,6 @@ Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message
521
528
  content,
522
529
  properties
523
530
  } = message;
524
- const id = this.id;
525
531
  const inboundQ = this.broker.getQueue('inbound-q');
526
532
  switch (routingKey) {
527
533
  case 'activity.enter':
@@ -540,23 +546,6 @@ Activity.prototype._onInboundEvent = function onInboundEvent(routingKey, message
540
546
  case 'flow.take':
541
547
  case 'flow.discard':
542
548
  return inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
543
- case 'association.discard':
544
- {
545
- this.logger.debug(`<${id}> compensation discarded`);
546
- return inboundQ.purge();
547
- }
548
- case 'association.complete':
549
- {
550
- if (!this[kFlags].isForCompensation) break;
551
- inboundQ.queueMessage(fields, (0, _messageHelper.cloneContent)(content), properties);
552
- const compensationId = `${(0, _shared.brokerSafeId)(id)}_${(0, _shared.brokerSafeId)(content.sequenceId)}`;
553
- this._publishEvent('compensation.start', this._createMessage({
554
- executionId: compensationId,
555
- placeholder: true
556
- }));
557
- this.logger.debug(`<${id}> start compensation with id <${compensationId}>`);
558
- return this._consumeInbound();
559
- }
560
549
  }
561
550
  };
562
551
  Activity.prototype._consumeRunQ = function consumeRunQ() {
@@ -640,6 +629,7 @@ Activity.prototype._continueRunMessage = function continueRunMessage(routingKey,
640
629
  {
641
630
  const execution = this.execution;
642
631
  if (!isRedelivered && execution) {
632
+ if (execution.completed) return message.ack();
643
633
  this[kExecuteMessage] = message;
644
634
  return execution.passthrough(message);
645
635
  }
@@ -763,6 +753,7 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
763
753
  });
764
754
  break;
765
755
  }
756
+ case 'execution.cancel':
766
757
  case 'execution.discard':
767
758
  this.status = 'discarded';
768
759
  broker.publish('run', 'run.discarded', content, {
@@ -783,7 +774,6 @@ Activity.prototype._onExecutionMessage = function onExecutionMessage(routingKey,
783
774
  Activity.prototype._ackRunExecuteMessage = function ackRunExecuteMessage() {
784
775
  if (this.environment.settings.step) return;
785
776
  const executeMessage = this[kExecuteMessage];
786
- this[kExecuteMessage] = null;
787
777
  executeMessage.ack();
788
778
  };
789
779
  Activity.prototype._doRunLeave = function doRunLeave(message, isDiscarded, onOutbound) {
@@ -171,10 +171,12 @@ ActivityExecution.prototype._onExecuteMessage = function onExecuteMessage(routin
171
171
  if (!this[kPostponed].length) return this.broker.publish('execution', 'execute.start', (0, _messageHelper.cloneContent)(this[kExecuteMessage].content));
172
172
  break;
173
173
  }
174
+ case 'execute.cancel':
175
+ return this._onExecutionDiscarded('cancel', message);
174
176
  case 'execute.error':
177
+ return this._onExecutionDiscarded('error', message);
175
178
  case 'execute.discard':
176
- return this._onExecutionDiscarded(message);
177
- case 'execute.cancel':
179
+ return this._onExecutionDiscarded('discard', message);
178
180
  case 'execute.completed':
179
181
  {
180
182
  if (isRedelivered) {
@@ -257,7 +259,7 @@ ActivityExecution.prototype._onExecutionCompleted = function onExecutionComplete
257
259
  ...message.content
258
260
  }, message.properties.correlationId);
259
261
  };
260
- ActivityExecution.prototype._onExecutionDiscarded = function onExecutionDiscarded(message) {
262
+ ActivityExecution.prototype._onExecutionDiscarded = function onExecutionDiscarded(discardType, message) {
261
263
  const postponedMsg = this._ackPostponed(message);
262
264
  const {
263
265
  isRootScope,
@@ -280,12 +282,7 @@ ActivityExecution.prototype._onExecutionDiscarded = function onExecutionDiscarde
280
282
  const subApis = this.getPostponed();
281
283
  postponed.splice(0);
282
284
  for (const api of subApis) api.discard();
283
- if (error) {
284
- return this._publishExecutionCompleted('error', (0, _messageHelper.cloneContent)(message.content, {
285
- error
286
- }), correlationId);
287
- }
288
- this._publishExecutionCompleted('discard', message.content, correlationId);
285
+ this._publishExecutionCompleted(discardType, (0, _messageHelper.cloneContent)(message.content), correlationId);
289
286
  };
290
287
  ActivityExecution.prototype._publishExecutionCompleted = function publishExecutionCompleted(completionType, completeContent, correlationId) {
291
288
  this[kCompleted] = true;
@@ -109,6 +109,11 @@ Object.defineProperty(Definition.prototype, 'stopped', {
109
109
  return this[kStopped];
110
110
  }
111
111
  });
112
+ Object.defineProperty(Definition.prototype, 'activityStatus', {
113
+ get() {
114
+ return this[kExec].execution && this[kExec].execution.activityStatus || 'idle';
115
+ }
116
+ });
112
117
  Definition.prototype.run = function run(optionsOrCallback, optionalCallback) {
113
118
  const [runOptions, callback] = (0, _shared.getOptionsAndCallback)(optionsOrCallback, optionalCallback);
114
119
  if (this.isRunning) {
@@ -173,7 +178,6 @@ Definition.prototype.recover = function recover(state) {
173
178
  };
174
179
  Definition.prototype.shake = function shake(startId) {
175
180
  let result = {};
176
- const broker = this.broker;
177
181
  let bps;
178
182
  if (startId) {
179
183
  const startActivity = this.getActivityById(startId);
@@ -182,26 +186,28 @@ Definition.prototype.shake = function shake(startId) {
182
186
  if (!bp) return;
183
187
  bps = [bp];
184
188
  } else bps = this.getProcesses();
185
- bps.forEach(shakeProcess);
186
- return result;
187
- function shakeProcess(shakeBp) {
188
- let shovel;
189
- if (!shakeBp.isRunning) {
190
- shovel = shakeBp.broker.createShovel('shaker', {
191
- exchange: 'event',
192
- pattern: '*.shake#'
193
- }, {
194
- broker,
195
- exchange: 'event'
196
- });
197
- }
198
- const shakeResult = shakeBp.shake(startId);
199
- if (shovel) shakeBp.broker.closeShovel('shaker');
189
+ bps.forEach(bp => {
200
190
  result = {
201
191
  ...result,
202
- ...shakeResult
192
+ ...this._shakeProcess(bp, startId)
203
193
  };
194
+ });
195
+ return result;
196
+ };
197
+ Definition.prototype._shakeProcess = function shakeProcess(shakeBp, startId) {
198
+ let shovel;
199
+ if (!shakeBp.isRunning) {
200
+ shovel = shakeBp.broker.createShovel('shaker', {
201
+ exchange: 'event',
202
+ pattern: '*.shake#'
203
+ }, {
204
+ broker: this.broker,
205
+ exchange: 'event'
206
+ });
204
207
  }
208
+ const shakeResult = shakeBp.shake(startId);
209
+ if (shovel) shakeBp.broker.closeShovel('shaker');
210
+ return shakeResult;
205
211
  };
206
212
  Definition.prototype.getState = function getState() {
207
213
  return this._createMessage({
@@ -96,6 +96,29 @@ Object.defineProperty(DefinitionExecution.prototype, 'isRunning', {
96
96
  return this[kActivated];
97
97
  }
98
98
  });
99
+ Object.defineProperty(DefinitionExecution.prototype, 'activityStatus', {
100
+ get() {
101
+ let status = 'idle';
102
+ const running = this[kProcesses].running;
103
+ if (!running || !running.length) return status;
104
+ for (const bp of running) {
105
+ const bpStatus = bp.activityStatus;
106
+ switch (bp.activityStatus) {
107
+ case 'idle':
108
+ break;
109
+ case 'executing':
110
+ return bpStatus;
111
+ case 'timer':
112
+ status = bpStatus;
113
+ break;
114
+ case 'wait':
115
+ if (status === 'idle') status = bpStatus;
116
+ break;
117
+ }
118
+ }
119
+ return status;
120
+ }
121
+ });
99
122
  DefinitionExecution.prototype.execute = function execute(executeMessage) {
100
123
  if (!executeMessage) throw new Error('Definition execution requires message');
101
124
  const content = executeMessage.content;
@@ -4,9 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = CancelEventDefinition;
7
- var _shared = require("../shared.js");
8
7
  var _messageHelper = require("../messageHelper.js");
9
- const kMessageQ = Symbol.for('cancelQ');
10
8
  const kCompleted = Symbol.for('completed');
11
9
  const kExecuteMessage = Symbol.for('executeMessage');
12
10
  function CancelEventDefinition(activity, eventDefinition) {
@@ -19,7 +17,7 @@ function CancelEventDefinition(activity, eventDefinition) {
19
17
  const type = eventDefinition.type;
20
18
  this.id = id;
21
19
  this.type = type;
22
- const reference = this.reference = {
20
+ this.reference = {
23
21
  referenceType: 'cancel'
24
22
  };
25
23
  this.isThrowing = isThrowing;
@@ -27,18 +25,6 @@ function CancelEventDefinition(activity, eventDefinition) {
27
25
  this.environment = environment;
28
26
  this.broker = broker;
29
27
  this.logger = environment.Logger(type.toLowerCase());
30
- if (!isThrowing) {
31
- this[kCompleted] = false;
32
- const messageQueueName = `${reference.referenceType}-${(0, _shared.brokerSafeId)(id)}-q`;
33
- this[kMessageQ] = broker.assertQueue(messageQueueName, {
34
- autoDelete: false,
35
- durable: true
36
- });
37
- broker.bindQueue(messageQueueName, 'api', `*.${reference.referenceType}.#`, {
38
- durable: true,
39
- priority: 400
40
- });
41
- }
42
28
  }
43
29
  Object.defineProperty(CancelEventDefinition.prototype, 'executionId', {
44
30
  get() {
@@ -59,88 +45,50 @@ CancelEventDefinition.prototype.executeCatch = function executeCatch(executeMess
59
45
  } = executeContent;
60
46
  const parentExecutionId = parent.executionId;
61
47
  const broker = this.broker;
62
- const onCatchMessage = this._onCatchMessage.bind(this);
63
- this[kMessageQ].consume(onCatchMessage, {
64
- noAck: true,
65
- consumerTag: `_oncancel-${executionId}`
66
- });
67
- if (this[kCompleted]) return;
68
- const onApiMessage = this._onApiMessage.bind(this);
69
- broker.subscribeTmp('api', `activity.#.${parentExecutionId}`, onApiMessage, {
70
- noAck: true,
71
- consumerTag: `_api-parent-${executionId}`
72
- });
73
- broker.subscribeTmp('api', `activity.#.${executionId}`, onApiMessage, {
48
+ this._debug('expect cancel');
49
+ broker.subscribeTmp('api', `activity.#.${parent.executionId}#`, this._onApiMessage.bind(this), {
74
50
  noAck: true,
75
51
  consumerTag: `_api-${executionId}`
76
52
  });
77
- this._debug('expect cancel');
78
- const exchangeKey = `execute.canceled.${executionId}`;
79
- broker.subscribeOnce('execution', exchangeKey, onCatchMessage, {
53
+ const expectRoutingKey = `execute.cancelled.${executionId}`;
54
+ broker.subscribeOnce('execution', expectRoutingKey, this._onCatchMessage.bind(this), {
80
55
  consumerTag: `_onattached-cancel-${executionId}`
81
56
  });
82
57
  broker.publish('execution', 'execute.expect', (0, _messageHelper.cloneContent)(executeContent, {
83
- pattern: '#.cancel',
58
+ pattern: 'activity.execution.cancel',
84
59
  exchange: 'execution',
85
- exchangeKey
60
+ expectRoutingKey
86
61
  }));
62
+ const waitContent = (0, _messageHelper.cloneContent)(executeContent, {
63
+ executionId: parentExecutionId,
64
+ condition: this.condition,
65
+ expect: 'cancel'
66
+ });
67
+ waitContent.parent = (0, _messageHelper.shiftParent)(parent);
68
+ broker.publish('event', 'activity.wait', waitContent);
87
69
  };
88
70
  CancelEventDefinition.prototype.executeThrow = function executeThrow(executeMessage) {
89
- const {
90
- isTransaction
91
- } = this.environment.variables.content || {};
92
71
  const executeContent = executeMessage.content;
93
72
  const {
94
73
  executionId,
95
74
  parent
96
75
  } = executeContent;
97
- this.logger.debug(`<${executionId} (${this.activity.id})> throw cancel${isTransaction ? ' transaction' : ''}`);
76
+ this.logger.debug(`<${executionId} (${this.activity.id})> throw cancel`);
98
77
  const broker = this.broker;
99
78
  const cancelContent = (0, _messageHelper.cloneContent)(executeContent, {
100
- isTransaction,
101
79
  executionId: parent.executionId,
102
80
  state: 'throw'
103
81
  });
104
82
  cancelContent.parent = (0, _messageHelper.shiftParent)(parent);
105
83
  broker.publish('event', 'activity.cancel', cancelContent, {
106
- type: 'cancel',
107
- delegate: isTransaction
84
+ type: 'cancel'
108
85
  });
109
86
  return broker.publish('execution', 'execute.completed', (0, _messageHelper.cloneContent)(executeContent));
110
87
  };
111
88
  CancelEventDefinition.prototype._onCatchMessage = function onCatchMessage(_, message) {
112
- if (message.content && message.content.isTransaction) return this._onCancelTransaction(_, message);
113
- this._debug(`cancel caught from <${message.content.id}>`);
114
- return this._complete(message.content.message);
115
- };
116
- CancelEventDefinition.prototype._onCancelTransaction = function onCancelTransaction(_, message) {
117
- const broker = this.broker,
118
- executionId = this.executionId;
119
- const executeContent = this[kExecuteMessage].content;
120
- broker.cancel(`_oncancel-${executionId}`);
121
- this._debug(`cancel transaction thrown by <${message.content.id}>`);
122
- broker.assertExchange('cancel', 'topic');
123
- broker.publish('execution', 'execute.detach', (0, _messageHelper.cloneContent)(executeContent, {
124
- pattern: '#',
125
- bindExchange: 'cancel',
126
- sourceExchange: 'event',
127
- sourcePattern: '#'
128
- }));
129
- broker.publish('event', 'activity.compensate', (0, _messageHelper.cloneContent)(message.content, {
130
- state: 'throw'
131
- }), {
132
- type: 'compensate',
133
- delegate: true
134
- });
135
- broker.subscribeTmp('cancel', 'activity.leave', (__, {
136
- content: msg
137
- }) => {
138
- if (msg.id !== executeContent.attachedTo) return;
139
- return this._complete(message.content.message);
140
- }, {
141
- noAck: true,
142
- consumerTag: `_oncancelend-${executionId}`
143
- });
89
+ const content = message.content;
90
+ this._debug(`cancel caught from <${content.id}>`);
91
+ return this._complete(content.message);
144
92
  };
145
93
  CancelEventDefinition.prototype._complete = function complete(output) {
146
94
  this[kCompleted] = true;
@@ -171,12 +119,8 @@ CancelEventDefinition.prototype._onApiMessage = function onApiMessage(routingKey
171
119
  CancelEventDefinition.prototype._stop = function stop() {
172
120
  const broker = this.broker,
173
121
  executionId = this.executionId;
174
- broker.cancel(`_api-parent-${executionId}`);
175
- broker.cancel(`_api-${executionId}`);
176
- broker.cancel(`_oncancel-${executionId}`);
177
- broker.cancel(`_oncancelend-${executionId}`);
178
122
  broker.cancel(`_onattached-cancel-${executionId}`);
179
- this[kMessageQ].purge();
123
+ broker.cancel(`_api-${executionId}`);
180
124
  };
181
125
  CancelEventDefinition.prototype._debug = function debug(msg) {
182
126
  this.logger.debug(`<${this.executionId} (${this.activity.id})> ${msg}`);