bpmn-elements 5.1.3 → 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +322 -0
  2. package/README.md +9 -3
  3. package/dist/index.js +71 -39
  4. package/dist/src/Api.js +77 -76
  5. package/dist/src/Context.js +169 -164
  6. package/dist/src/Environment.js +90 -102
  7. package/dist/src/EventBroker.js +89 -88
  8. package/dist/src/ExtensionsMapper.js +2 -2
  9. package/dist/src/MessageFormatter.js +164 -95
  10. package/dist/src/Scripts.js +6 -2
  11. package/dist/src/Timers.js +4 -6
  12. package/dist/src/activity/Activity.js +1108 -901
  13. package/dist/src/activity/ActivityExecution.js +342 -297
  14. package/dist/src/activity/Dummy.js +3 -3
  15. package/dist/src/definition/Definition.js +498 -444
  16. package/dist/src/definition/DefinitionExecution.js +722 -409
  17. package/dist/src/error/Errors.js +17 -7
  18. package/dist/src/eventDefinitions/CancelEventDefinition.js +190 -150
  19. package/dist/src/eventDefinitions/CompensateEventDefinition.js +194 -161
  20. package/dist/src/eventDefinitions/ConditionalEventDefinition.js +197 -135
  21. package/dist/src/eventDefinitions/ErrorEventDefinition.js +207 -165
  22. package/dist/src/eventDefinitions/EscalationEventDefinition.js +175 -141
  23. package/dist/src/eventDefinitions/EventDefinitionExecution.js +157 -129
  24. package/dist/src/eventDefinitions/LinkEventDefinition.js +174 -149
  25. package/dist/src/eventDefinitions/MessageEventDefinition.js +213 -176
  26. package/dist/src/eventDefinitions/SignalEventDefinition.js +203 -161
  27. package/dist/src/eventDefinitions/TerminateEventDefinition.js +21 -23
  28. package/dist/src/eventDefinitions/TimerEventDefinition.js +243 -228
  29. package/dist/src/events/BoundaryEvent.js +180 -144
  30. package/dist/src/events/EndEvent.js +18 -23
  31. package/dist/src/events/IntermediateCatchEvent.js +44 -58
  32. package/dist/src/events/IntermediateThrowEvent.js +18 -23
  33. package/dist/src/events/StartEvent.js +109 -94
  34. package/dist/src/flows/Association.js +94 -101
  35. package/dist/src/flows/MessageFlow.js +86 -103
  36. package/dist/src/flows/SequenceFlow.js +172 -184
  37. package/dist/src/gateways/EventBasedGateway.js +88 -84
  38. package/dist/src/gateways/ExclusiveGateway.js +13 -16
  39. package/dist/src/gateways/InclusiveGateway.js +11 -14
  40. package/dist/src/gateways/ParallelGateway.js +11 -14
  41. package/dist/src/getPropertyValue.js +34 -34
  42. package/dist/src/io/BpmnIO.js +31 -0
  43. package/dist/src/io/EnvironmentDataObject.js +33 -29
  44. package/dist/src/io/EnvironmentDataStore.js +52 -0
  45. package/dist/src/io/EnvironmentDataStoreReference.js +52 -0
  46. package/dist/src/io/InputOutputSpecification.js +177 -168
  47. package/dist/src/io/Properties.js +252 -0
  48. package/dist/src/messageHelper.js +1 -1
  49. package/dist/src/process/Process.js +433 -359
  50. package/dist/src/process/ProcessExecution.js +744 -645
  51. package/dist/src/shared.js +3 -6
  52. package/dist/src/tasks/CallActivity.js +160 -0
  53. package/dist/src/tasks/LoopCharacteristics.js +309 -330
  54. package/dist/src/tasks/ReceiveTask.js +233 -182
  55. package/dist/src/tasks/ScriptTask.js +35 -41
  56. package/dist/src/tasks/ServiceImplementation.js +13 -20
  57. package/dist/src/tasks/ServiceTask.js +82 -75
  58. package/dist/src/tasks/SignalTask.js +97 -93
  59. package/dist/src/tasks/StandardLoopCharacteristics.js +1 -1
  60. package/dist/src/tasks/SubProcess.js +195 -175
  61. package/dist/src/tasks/Task.js +17 -19
  62. package/index.js +8 -0
  63. package/package.json +16 -15
  64. package/src/Api.js +65 -59
  65. package/src/Context.js +142 -132
  66. package/src/Environment.js +88 -100
  67. package/src/EventBroker.js +67 -68
  68. package/src/ExtensionsMapper.js +2 -2
  69. package/src/MessageFormatter.js +132 -74
  70. package/src/Timers.js +4 -4
  71. package/src/activity/Activity.js +916 -757
  72. package/src/activity/ActivityExecution.js +293 -247
  73. package/src/activity/Dummy.js +2 -2
  74. package/src/definition/Definition.js +436 -401
  75. package/src/definition/DefinitionExecution.js +603 -343
  76. package/src/error/Errors.js +11 -6
  77. package/src/eventDefinitions/CancelEventDefinition.js +164 -121
  78. package/src/eventDefinitions/CompensateEventDefinition.js +158 -124
  79. package/src/eventDefinitions/ConditionalEventDefinition.js +147 -104
  80. package/src/eventDefinitions/ErrorEventDefinition.js +190 -131
  81. package/src/eventDefinitions/EscalationEventDefinition.js +139 -101
  82. package/src/eventDefinitions/EventDefinitionExecution.js +127 -95
  83. package/src/eventDefinitions/LinkEventDefinition.js +160 -129
  84. package/src/eventDefinitions/MessageEventDefinition.js +178 -121
  85. package/src/eventDefinitions/SignalEventDefinition.js +162 -106
  86. package/src/eventDefinitions/TerminateEventDefinition.js +19 -19
  87. package/src/eventDefinitions/TimerEventDefinition.js +202 -167
  88. package/src/events/BoundaryEvent.js +156 -115
  89. package/src/events/EndEvent.js +15 -18
  90. package/src/events/IntermediateCatchEvent.js +40 -44
  91. package/src/events/IntermediateThrowEvent.js +15 -18
  92. package/src/events/StartEvent.js +84 -50
  93. package/src/flows/Association.js +98 -113
  94. package/src/flows/MessageFlow.js +81 -97
  95. package/src/flows/SequenceFlow.js +145 -163
  96. package/src/gateways/EventBasedGateway.js +75 -68
  97. package/src/gateways/ExclusiveGateway.js +8 -13
  98. package/src/gateways/InclusiveGateway.js +8 -13
  99. package/src/gateways/ParallelGateway.js +8 -13
  100. package/src/getPropertyValue.js +34 -33
  101. package/src/io/BpmnIO.js +20 -0
  102. package/src/io/EnvironmentDataObject.js +29 -18
  103. package/src/io/EnvironmentDataStore.js +33 -0
  104. package/src/io/EnvironmentDataStoreReference.js +33 -0
  105. package/src/io/InputOutputSpecification.js +154 -157
  106. package/src/io/Properties.js +199 -0
  107. package/src/process/Process.js +374 -333
  108. package/src/process/ProcessExecution.js +606 -554
  109. package/src/shared.js +1 -5
  110. package/src/tasks/CallActivity.js +130 -0
  111. package/src/tasks/LoopCharacteristics.js +290 -289
  112. package/src/tasks/ReceiveTask.js +174 -107
  113. package/src/tasks/ScriptTask.js +27 -30
  114. package/src/tasks/ServiceImplementation.js +13 -18
  115. package/src/tasks/ServiceTask.js +67 -60
  116. package/src/tasks/SignalTask.js +77 -52
  117. package/src/tasks/StandardLoopCharacteristics.js +1 -1
  118. package/src/tasks/SubProcess.js +184 -157
  119. package/src/tasks/Task.js +15 -19
@@ -5,500 +5,535 @@ import {getUniqueId, getOptionsAndCallback} from '../shared';
5
5
  import {makeErrorFromMessage} from '../error/Errors';
6
6
  import {cloneMessage, cloneContent} from '../messageHelper';
7
7
 
8
+ const consumingSymbol = Symbol.for('consuming');
9
+ const countersSymbol = Symbol.for('counters');
10
+ const execSymbol = Symbol.for('exec');
11
+ const executeMessageSymbol = Symbol.for('executeMessage');
12
+ const messageHandlersSymbol = Symbol.for('messageHandlers');
13
+ const stateMessageSymbol = Symbol.for('stateMessage');
14
+ const statusSymbol = Symbol.for('status');
15
+ const stoppedSymbol = Symbol.for('stopped');
16
+
8
17
  export default Definition;
9
18
 
10
19
  export function Definition(context, options) {
20
+ if (!(this instanceof Definition)) return new Definition(context, options);
11
21
  if (!context) throw new Error('No context');
12
22
 
13
23
  const {id, name, type = 'definition'} = context;
14
- let environment = context.environment;
24
+ this.id = id;
25
+ this.type = type;
26
+ this.name = name;
15
27
 
28
+ let environment;
16
29
  if (options) {
17
- environment = environment.clone(options);
18
- context = context.clone(environment);
30
+ environment = this.environment = context.environment.clone(options);
31
+ this.context = context.clone(environment);
32
+ } else {
33
+ environment = this.environment = context.environment;
34
+ this.context = context;
19
35
  }
20
36
 
21
- const logger = environment.Logger(type.toLowerCase());
22
-
23
- let execution, executionId, processes, executableProcesses, postponedMessage, stateMessage, stopped, consumingRunQ;
24
- let status;
25
-
26
- let counters = {
37
+ this[countersSymbol] = {
27
38
  completed: 0,
28
39
  discarded: 0,
29
40
  };
30
41
 
31
- const definitionApi = {
32
- id,
33
- name,
34
- type,
35
- logger,
36
- context,
37
- get counters() {
38
- return {...counters};
39
- },
40
- get executionId() {
41
- return executionId;
42
- },
43
- get status() {
44
- return status;
45
- },
46
- get execution() {
47
- return execution;
48
- },
49
- get isRunning() {
50
- if (!consumingRunQ) return false;
51
- return !!status;
52
- },
53
- get environment() {
54
- return environment;
55
- },
56
- run,
57
- getApi,
58
- getState,
59
- getActivityById,
60
- getElementById,
61
- getPostponed,
62
- getProcesses,
63
- getExecutableProcesses,
64
- getProcessById,
65
- sendMessage,
66
- recover,
67
- resume,
68
- shake,
69
- signal,
70
- cancelActivity,
71
- stop,
42
+ this[stoppedSymbol] = false;
43
+ this[execSymbol] = {};
44
+
45
+ const onBrokerReturn = this._onBrokerReturnFn.bind(this);
46
+ this[messageHandlersSymbol] = {
47
+ onBrokerReturn,
48
+ onApiMessage: this._onApiMessage.bind(this),
49
+ onRunMessage: this._onRunMessage.bind(this),
50
+ onExecutionMessage: this._onExecutionMessage.bind(this),
72
51
  };
73
52
 
74
- const {broker, on, once, waitFor, emit, emitFatal} = DefinitionBroker(definitionApi, onBrokerReturn);
53
+ const {broker, on, once, waitFor, emit, emitFatal} = DefinitionBroker(this, onBrokerReturn);
54
+ this.broker = broker;
75
55
 
76
- definitionApi.on = on;
77
- definitionApi.once = once;
78
- definitionApi.waitFor = waitFor;
79
- definitionApi.emit = emit;
80
- definitionApi.emitFatal = emitFatal;
56
+ this.on = on;
57
+ this.once = once;
58
+ this.waitFor = waitFor;
59
+ this.emit = emit;
60
+ this.emitFatal = emitFatal;
81
61
 
82
- const runQ = broker.getQueue('run-q');
83
- const executionQ = broker.getQueue('execution-q');
62
+ this.logger = environment.Logger(type.toLowerCase());
63
+ }
84
64
 
85
- Object.defineProperty(definitionApi, 'broker', {
86
- enumerable: true,
87
- get: () => broker,
88
- });
65
+ const proto = Definition.prototype;
66
+
67
+ Object.defineProperty(proto, 'counters', {
68
+ enumerable: true,
69
+ get() {
70
+ return {...this[countersSymbol]};
71
+ },
72
+ });
73
+
74
+ Object.defineProperty(proto, 'execution', {
75
+ enumerable: true,
76
+ get() {
77
+ return this[execSymbol].execution;
78
+ },
79
+ });
80
+
81
+ Object.defineProperty(proto, 'executionId', {
82
+ enumerable: true,
83
+ get() {
84
+ return this[execSymbol].executionId;
85
+ },
86
+ });
87
+
88
+ Object.defineProperty(proto, 'isRunning', {
89
+ enumerable: true,
90
+ get() {
91
+ if (!this[consumingSymbol]) return false;
92
+ return !!this.status;
93
+ },
94
+ });
95
+
96
+ Object.defineProperty(proto, 'status', {
97
+ enumerable: true,
98
+ get() {
99
+ return this[statusSymbol];
100
+ },
101
+ });
102
+
103
+ Object.defineProperty(proto, 'stopped', {
104
+ enumerable: true,
105
+ get() {
106
+ return this[stoppedSymbol];
107
+ },
108
+ });
109
+
110
+ proto.run = function run(optionsOrCallback, optionalCallback) {
111
+ const [runOptions, callback] = getOptionsAndCallback(optionsOrCallback, optionalCallback);
112
+ if (this.isRunning) {
113
+ const err = new Error('definition is already running');
114
+ if (callback) return callback(err);
115
+ throw err;
116
+ }
89
117
 
90
- Object.defineProperty(definitionApi, 'stopped', {
91
- enumerable: true,
92
- get: () => execution && execution.stopped,
93
- });
118
+ if (callback) {
119
+ addConsumerCallbacks(this, callback);
120
+ }
94
121
 
95
- return definitionApi;
122
+ const exec = this[execSymbol];
123
+ exec.executionId = getUniqueId(this.id);
124
+ const content = this._createMessage({...runOptions});
96
125
 
97
- function run(optionsOrCallback, optionalCallback) {
98
- const [runOptions, callback] = getOptionsAndCallback(optionsOrCallback, optionalCallback);
99
- if (definitionApi.isRunning) {
100
- const err = new Error('definition is already running');
101
- if (callback) return callback(err);
102
- throw err;
103
- }
126
+ const broker = this.broker;
127
+ broker.publish('run', 'run.enter', content);
128
+ broker.publish('run', 'run.start', cloneContent(content));
129
+ broker.publish('run', 'run.execute', cloneContent(content));
104
130
 
105
- addConsumerCallbacks(callback);
131
+ this.logger.debug(`<${this.executionId} (${this.id})> run`);
106
132
 
107
- executionId = getUniqueId(id);
108
- const content = createMessage({...runOptions, executionId});
133
+ this._activateRunConsumers();
109
134
 
110
- broker.publish('run', 'run.enter', content);
111
- broker.publish('run', 'run.start', cloneContent(content));
112
- broker.publish('run', 'run.execute', cloneContent(content));
135
+ return this;
136
+ };
113
137
 
114
- logger.debug(`<${executionId} (${id})> run`);
138
+ proto.resume = function resume(callback) {
139
+ if (this.isRunning) {
140
+ const err = new Error('cannot resume running definition');
141
+ if (callback) return callback(err);
142
+ throw err;
143
+ }
115
144
 
116
- activateRunConsumers();
145
+ this[stoppedSymbol] = false;
146
+ if (!this.status) return this;
117
147
 
118
- return definitionApi;
148
+ if (callback) {
149
+ addConsumerCallbacks(this, callback);
119
150
  }
120
151
 
121
- function resume(callback) {
122
- if (definitionApi.isRunning) {
123
- const err = new Error('cannot resume running definition');
124
- if (callback) return callback(err);
125
- throw err;
126
- }
152
+ this.logger.debug(`<${this.executionId} (${this.id})> resume`);
127
153
 
128
- stopped = false;
129
- if (!status) return definitionApi;
154
+ const content = this._createMessage();
155
+ this.broker.publish('run', 'run.resume', content, {persistent: false});
156
+ this._activateRunConsumers();
157
+ return this;
158
+ };
130
159
 
131
- addConsumerCallbacks(callback);
160
+ proto.recover = function recover(state) {
161
+ if (this.isRunning) throw new Error('cannot recover running definition');
162
+ if (!state) return this;
132
163
 
133
- logger.debug(`<${executionId} (${id})> resume`);
164
+ this[stoppedSymbol] = !!state.stopped;
165
+ this[statusSymbol] = state.status;
134
166
 
135
- const content = createMessage({executionId});
136
- broker.publish('run', 'run.resume', content, {persistent: false});
137
- activateRunConsumers();
138
- return definitionApi;
167
+ const exec = this[execSymbol];
168
+ exec.executionId = state.executionId;
169
+ if (state.counters) {
170
+ this[countersSymbol] = {...this[countersSymbol], ...state.counters};
139
171
  }
140
172
 
141
- function recover(state) {
142
- if (definitionApi.isRunning) throw new Error('cannot recover running definition');
143
- if (!state) return definitionApi;
144
-
145
- stopped = state.stopped;
146
- status = state.status;
173
+ this.environment.recover(state.environment);
147
174
 
148
- executionId = state.executionId;
149
- if (state.counters) {
150
- counters = {...counters, ...state.counters};
151
- }
152
-
153
- environment.recover(state.environment);
175
+ if (state.execution) {
176
+ exec.execution = new DefinitionExecution(this, this.context).recover(state.execution);
177
+ }
154
178
 
155
- if (state.execution) {
156
- execution = DefinitionExecution(definitionApi, context).recover(state.execution);
179
+ this.broker.recover(state.broker);
180
+
181
+ return this;
182
+ };
183
+
184
+ proto.shake = function shake(startId) {
185
+ let result = {};
186
+ const broker = this.broker;
187
+
188
+ let bps;
189
+ if (startId) {
190
+ const startActivity = this.getActivityById(startId);
191
+ if (!startActivity) return;
192
+ const bp = this.getProcessById(startActivity.parent.id);
193
+ if (!bp) return;
194
+ bps = [bp];
195
+ } else bps = this.getProcesses();
196
+
197
+ bps.forEach(shakeProcess);
198
+
199
+ return result;
200
+
201
+ function shakeProcess(shakeBp) {
202
+ let shovel;
203
+ if (!shakeBp.isRunning) {
204
+ shovel = shakeBp.broker.createShovel('shaker', {
205
+ exchange: 'event',
206
+ pattern: '*.shake#',
207
+ }, {
208
+ broker,
209
+ exchange: 'event',
210
+ });
157
211
  }
158
212
 
159
- broker.recover(state.broker);
213
+ const shakeResult = shakeBp.shake(startId);
214
+ if (shovel) shakeBp.broker.closeShovel('shaker');
160
215
 
161
- return definitionApi;
216
+ result = {
217
+ ...result,
218
+ ...shakeResult,
219
+ };
162
220
  }
163
-
164
- function shake(startId) {
165
- let result = {};
166
-
167
- let bps;
168
- if (startId) {
169
- const startActivity = getActivityById(startId);
170
- if (!startActivity) return;
171
- const bp = getProcessById(startActivity.parent.id);
172
- if (!bp) return;
173
- bps = [bp];
174
- } else bps = getProcesses();
175
-
176
- bps.forEach(shakeProcess);
177
-
178
- return result;
179
-
180
- function shakeProcess(shakeBp) {
181
- let shovel;
182
- if (!shakeBp.isRunning) {
183
- shovel = shakeBp.broker.createShovel('shaker', {
184
- exchange: 'event',
185
- pattern: '*.shake#',
186
- }, {
187
- broker,
188
- exchange: 'event',
189
- });
190
- }
191
-
192
- const shakeResult = shakeBp.shake(startId);
193
- if (shovel) shakeBp.broker.closeShovel('shaker');
194
-
195
- result = {
196
- ...result,
197
- ...shakeResult,
198
- };
199
- }
221
+ };
222
+
223
+ proto.getState = function getState() {
224
+ return this._createMessage({
225
+ status: this.status,
226
+ stopped: this.stopped,
227
+ counters: this.counters,
228
+ environment: this.environment.getState(),
229
+ execution: this.execution && this.execution.getState(),
230
+ broker: this.broker.getState(true),
231
+ });
232
+ };
233
+
234
+ proto.getProcesses = function getProcesses() {
235
+ const execution = this.execution;
236
+ if (execution) return execution.getProcesses();
237
+ return this.context.getProcesses();
238
+ };
239
+
240
+ proto.getExecutableProcesses = function getExecutableProcesses() {
241
+ const execution = this.execution;
242
+ if (execution) return execution.getExecutableProcesses();
243
+ return this.context.getExecutableProcesses();
244
+ };
245
+
246
+ proto.getRunningProcesses = function getRunningProcesses() {
247
+ const execution = this.execution;
248
+ if (!execution) return [];
249
+ return execution.getRunningProcesses();
250
+ };
251
+
252
+ proto.getProcessById = function getProcessById(processId) {
253
+ return this.getProcesses().find((p) => p.id === processId);
254
+ };
255
+
256
+ proto.getActivityById = function getActivityById(childId) {
257
+ const siblings = this.getProcesses();
258
+ for (const sibling of siblings) {
259
+ const child = sibling.getActivityById(childId);
260
+ if (child) return child;
200
261
  }
201
-
202
- function activateRunConsumers() {
203
- consumingRunQ = true;
204
- broker.subscribeTmp('api', `definition.*.${executionId}`, onApiMessage, {noAck: true, consumerTag: '_definition-api'});
205
- runQ.assertConsumer(onRunMessage, {exclusive: true, consumerTag: '_definition-run'});
262
+ return null;
263
+ };
264
+
265
+ proto.getElementById = function getElementById(elementId) {
266
+ return this.context.getActivityById(elementId);
267
+ };
268
+
269
+ proto.getPostponed = function getPostponed(...args) {
270
+ const execution = this.execution;
271
+ if (!execution) return [];
272
+ return execution.getPostponed(...args);
273
+ };
274
+
275
+ proto.getApi = function getApi(message) {
276
+ const execution = this.execution;
277
+ if (execution) return execution.getApi(message);
278
+ message = message || this[stateMessageSymbol];
279
+ if (!message) throw new Error('Definition is not running');
280
+ return DefinitionApi(this.broker, message);
281
+ };
282
+
283
+ proto.signal = function signal(message) {
284
+ return this.getApi().signal(message, {delegate: true});
285
+ };
286
+
287
+ proto.cancelActivity = function cancelActivity(message) {
288
+ return this.getApi().cancel(message, {delegate: true});
289
+ };
290
+
291
+ proto.sendMessage = function sendMessage(message) {
292
+ const messageContent = {message};
293
+ let messageType = 'message';
294
+ const reference = message && message.id && this.getElementById(message.id);
295
+ if (reference && reference.resolve) {
296
+ const resolvedReference = reference.resolve(this._createMessage({message}));
297
+ messageType = resolvedReference.messageType || messageType;
298
+ messageContent.message = {...message, ...resolvedReference};
206
299
  }
207
300
 
208
- function deactivateRunConsumers() {
209
- broker.cancel('_definition-api');
210
- broker.cancel('_definition-run');
211
- broker.cancel('_definition-execution');
212
- consumingRunQ = false;
213
- }
301
+ return this.getApi().sendApiMessage(messageType, messageContent, {delegate: true});
302
+ };
303
+
304
+ proto.stop = function stop() {
305
+ if (!this.isRunning) return;
306
+ this.getApi().stop();
307
+ };
308
+
309
+ proto._activateRunConsumers = function activateRunConsumers() {
310
+ this[consumingSymbol] = true;
311
+ const broker = this.broker;
312
+ const {onApiMessage, onRunMessage} = this[messageHandlersSymbol];
313
+ broker.subscribeTmp('api', `definition.*.${this.executionId}`, onApiMessage, {
314
+ noAck: true,
315
+ consumerTag: '_definition-api',
316
+ });
317
+ broker.getQueue('run-q').assertConsumer(onRunMessage, {
318
+ exclusive: true,
319
+ consumerTag: '_definition-run',
320
+ });
321
+ };
322
+
323
+ proto._deactivateRunConsumers = function deactivateRunConsumers() {
324
+ const broker = this.broker;
325
+ broker.cancel('_definition-api');
326
+ broker.cancel('_definition-run');
327
+ broker.cancel('_definition-execution');
328
+ this[consumingSymbol] = false;
329
+ };
330
+
331
+ proto._createMessage = function createMessage(override) {
332
+ return {
333
+ id: this.id,
334
+ type: this.type,
335
+ name: this.name,
336
+ executionId: this.executionId,
337
+ ...override,
338
+ };
339
+ };
214
340
 
215
- function stop() {
216
- if (!definitionApi.isRunning) return;
217
- getApi().stop();
341
+ proto._onRunMessage = function onRunMessage(routingKey, message) {
342
+ const {content, fields} = message;
343
+ if (routingKey === 'run.resume') {
344
+ return this._onResumeMessage(message);
218
345
  }
219
346
 
220
- function addConsumerCallbacks(callback) {
221
- if (!callback) return;
222
-
223
- broker.off('return', onBrokerReturn);
347
+ const exec = this[execSymbol];
348
+ this[stateMessageSymbol] = message;
224
349
 
225
- clearConsumers();
350
+ switch (routingKey) {
351
+ case 'run.enter': {
352
+ this.logger.debug(`<${this.executionId} (${this.id})> enter`);
226
353
 
227
- broker.subscribeOnce('event', 'definition.stop', cbLeave, {consumerTag: '_definition-callback-stop'});
228
- broker.subscribeOnce('event', 'definition.leave', cbLeave, {consumerTag: '_definition-callback-leave'});
229
- broker.subscribeOnce('event', 'definition.error', cbError, {consumerTag: '_definition-callback-error'});
354
+ this[statusSymbol] = 'entered';
355
+ if (fields.redelivered) break;
230
356
 
231
- function cbLeave(_, message) {
232
- clearConsumers();
233
- return callback(null, getApi(message));
357
+ exec.execution = undefined;
358
+ this._publishEvent('enter', content);
359
+ break;
234
360
  }
235
- function cbError(_, message) {
236
- clearConsumers();
237
- reset();
238
- const err = makeErrorFromMessage(message);
239
- return callback(err);
240
- }
241
-
242
- function clearConsumers() {
243
- broker.cancel('_definition-callback-stop');
244
- broker.cancel('_definition-callback-leave');
245
- broker.cancel('_definition-callback-error');
246
- broker.on('return', onBrokerReturn);
361
+ case 'run.start': {
362
+ this.logger.debug(`<${this.executionId} (${this.id})> start`);
363
+ this[statusSymbol] = 'start';
364
+ this._publishEvent('start', content);
365
+ break;
247
366
  }
248
- }
249
-
250
- function createMessage(override) {
251
- return {
252
- id,
253
- type,
254
- name,
255
- ...override,
256
- };
257
- }
258
-
259
- function onBrokerReturn(message) {
260
- if (message.properties.type === 'error') {
261
- deactivateRunConsumers();
262
- const err = makeErrorFromMessage(message);
263
- throw err;
264
- }
265
- }
266
-
267
- function onRunMessage(routingKey, message) {
268
- const {content, ack, fields} = message;
269
- if (routingKey === 'run.resume') {
270
- return onResumeMessage();
271
- }
272
-
273
- stateMessage = message;
274
-
275
- switch (routingKey) {
276
- case 'run.enter': {
277
- logger.debug(`<${executionId} (${id})> enter`);
278
-
279
- status = 'entered';
280
- if (fields.redelivered) break;
281
-
282
- execution = undefined;
283
- publishEvent('enter', content);
284
- break;
367
+ case 'run.execute': {
368
+ this[statusSymbol] = 'executing';
369
+ const executeMessage = cloneMessage(message);
370
+ if (fields.redelivered && !exec.execution) {
371
+ executeMessage.fields.redelivered = undefined;
285
372
  }
286
- case 'run.start': {
287
- logger.debug(`<${executionId} (${id})> start`);
288
- status = 'start';
289
- publishEvent('start', content);
290
- break;
291
- }
292
- case 'run.execute': {
293
- status = 'executing';
294
- const executeMessage = cloneMessage(message);
295
- if (fields.redelivered && !execution) {
296
- executeMessage.fields.redelivered = undefined;
297
- }
298
- postponedMessage = message;
299
- executionQ.assertConsumer(onExecutionMessage, {exclusive: true, consumerTag: '_definition-execution'});
300
-
301
- execution = execution || DefinitionExecution(definitionApi, context);
302
-
303
- if (executeMessage.fields.redelivered) {
304
- publishEvent('resume', content);
305
- }
306
-
307
- return execution.execute(executeMessage);
308
- }
309
- case 'run.end': {
310
- if (status === 'end') break;
373
+ this[executeMessageSymbol] = message;
374
+ this.broker.getQueue('execution-q').assertConsumer(this[messageHandlersSymbol].onExecutionMessage, {
375
+ exclusive: true,
376
+ consumerTag: '_definition-execution',
377
+ });
311
378
 
312
- counters.completed++;
379
+ exec.execution = exec.execution || new DefinitionExecution(this, this.context);
313
380
 
314
- logger.debug(`<${executionId} (${id})> completed`);
315
- status = 'end';
316
- broker.publish('run', 'run.leave', content);
317
- publishEvent('end', content);
318
- break;
381
+ if (executeMessage.fields.redelivered) {
382
+ this._publishEvent('resume', content);
319
383
  }
320
- case 'run.discarded': {
321
- if (status === 'discarded') break;
322
384
 
323
- counters.discarded++;
385
+ return exec.execution.execute(executeMessage);
386
+ }
387
+ case 'run.end': {
388
+ if (this.status === 'end') break;
324
389
 
325
- status = 'discarded';
326
- broker.publish('run', 'run.leave', content);
327
- break;
328
- }
329
- case 'run.error': {
330
- publishEvent('error', cloneContent(content, {
331
- error: fields.redelivered ? makeErrorFromMessage(message) : content.error,
332
- }), {mandatory: true});
333
- break;
334
- }
335
- case 'run.leave': {
336
- ack();
337
- status = undefined;
338
- deactivateRunConsumers();
390
+ this[countersSymbol].completed++;
339
391
 
340
- publishEvent('leave');
341
- break;
342
- }
392
+ this.logger.debug(`<${this.executionId} (${this.id})> completed`);
393
+ this[statusSymbol] = 'end';
394
+ this.broker.publish('run', 'run.leave', content);
395
+ this._publishEvent('end', content);
396
+ break;
343
397
  }
398
+ case 'run.error': {
399
+ this._publishEvent('error', {
400
+ ...content,
401
+ error: fields.redelivered ? makeErrorFromMessage(message) : content.error,
402
+ }, {mandatory: true});
403
+ break;
404
+ }
405
+ case 'run.discarded': {
406
+ if (this.status === 'discarded') break;
344
407
 
345
- ack();
408
+ this[countersSymbol].discarded++;
346
409
 
347
- function onResumeMessage() {
410
+ this[statusSymbol] = 'discarded';
411
+ this.broker.publish('run', 'run.leave', content);
412
+ break;
413
+ }
414
+ case 'run.leave': {
348
415
  message.ack();
416
+ this[statusSymbol] = undefined;
417
+ this._deactivateRunConsumers();
349
418
 
350
- switch (stateMessage.fields.routingKey) {
351
- case 'run.enter':
352
- case 'run.start':
353
- case 'run.discarded':
354
- case 'run.end':
355
- case 'run.leave':
356
- break;
357
- default:
358
- return;
359
- }
360
-
361
- if (!stateMessage.fields.redelivered) return;
362
-
363
- logger.debug(`<${id}> resume from ${status}`);
364
-
365
- return broker.publish('run', stateMessage.fields.routingKey, cloneContent(stateMessage.content), stateMessage.properties);
419
+ this._publishEvent('leave', this._createMessage());
420
+ return;
366
421
  }
367
422
  }
368
423
 
369
- function onExecutionMessage(routingKey, message) {
370
- const {content, properties} = message;
371
- const messageType = properties.type;
424
+ message.ack();
425
+ };
372
426
 
373
- message.ack();
427
+ proto._onResumeMessage = function onResumeMessage(message) {
428
+ message.ack();
374
429
 
375
- switch (messageType) {
376
- case 'stopped': {
377
- deactivateRunConsumers();
378
- return publishEvent('stop');
379
- }
380
- case 'error': {
381
- broker.publish('run', 'run.error', content);
382
- broker.publish('run', 'run.discarded', content);
383
- break;
384
- }
385
- default: {
386
- broker.publish('run', 'run.end', content);
387
- }
388
- }
430
+ const stateMessage = this[stateMessageSymbol];
389
431
 
390
- if (postponedMessage) {
391
- const ackMessage = postponedMessage;
392
- postponedMessage = null;
393
- ackMessage.ack();
394
- }
432
+ switch (stateMessage.fields.routingKey) {
433
+ case 'run.discarded':
434
+ case 'run.end':
435
+ case 'run.leave':
436
+ break;
437
+ default:
438
+ return;
395
439
  }
396
440
 
397
- function publishEvent(action, content = {}, msgOpts) {
398
- broker.publish('event', `definition.${action}`, execution ? execution.createMessage(content) : content, {type: action, ...msgOpts});
399
- }
441
+ if (!stateMessage.fields.redelivered) return;
400
442
 
401
- function getState() {
402
- return createMessage({
403
- executionId,
404
- status,
405
- stopped,
406
- counters: {...counters},
407
- environment: environment.getState(),
408
- execution: execution && execution.getState(),
409
- broker: broker.getState(),
410
- });
411
- }
443
+ this._debug(`resume from ${this.status}`);
412
444
 
413
- function getProcesses() {
414
- if (!processes) loadProcesses();
415
- return processes;
416
- }
445
+ return this.broker.publish('run', stateMessage.fields.routingKey, cloneContent(stateMessage.content), stateMessage.properties);
446
+ };
417
447
 
418
- function getExecutableProcesses() {
419
- if (!processes) loadProcesses();
420
- return executableProcesses;
421
- }
422
-
423
- function getProcessById(processId) {
424
- return getProcesses().find((p) => p.id === processId);
425
- }
448
+ proto._onExecutionMessage = function onExecutionMessage(routingKey, message) {
449
+ const {content, properties} = message;
450
+ const messageType = properties.type;
426
451
 
427
- function loadProcesses() {
428
- if (processes) return processes;
429
- executableProcesses = context.getExecutableProcesses() || [];
430
- processes = context.getProcesses() || [];
431
- logger.debug(`<${id}> found ${processes.length} processes`);
432
- }
452
+ message.ack();
433
453
 
434
- function getActivityById(childId) {
435
- let child;
436
- const siblings = getProcesses();
437
- for (let i = 0; i < siblings.length; i++) {
438
- child = siblings[i].getActivityById(childId);
439
- if (child) return child;
454
+ switch (messageType) {
455
+ case 'stopped': {
456
+ return this._onStop();
457
+ }
458
+ case 'error': {
459
+ this.broker.publish('run', 'run.error', content);
460
+ this.broker.publish('run', 'run.discarded', content);
461
+ break;
462
+ }
463
+ default: {
464
+ this.broker.publish('run', 'run.end', content);
440
465
  }
441
- return child;
442
- }
443
-
444
- function getElementById(elementId) {
445
- return context.getActivityById(elementId);
446
466
  }
447
467
 
448
- function getPostponed(...args) {
449
- if (!execution) return [];
450
- return execution.getPostponed(...args);
451
- }
468
+ const executeMessage = this[executeMessageSymbol];
469
+ this[executeMessageSymbol] = null;
470
+ executeMessage.ack();
471
+ };
452
472
 
453
- function getApi(message) {
454
- if (execution) return execution.getApi(message);
455
- if (!message || !stateMessage) throw new Error('Definition is not running');
456
- return DefinitionApi(broker, message || stateMessage);
473
+ proto._onApiMessage = function onApiMessage(routingKey, message) {
474
+ if (message.properties.type === 'stop') {
475
+ const execution = this.execution;
476
+ if (!execution || execution.completed) {
477
+ this._onStop();
478
+ }
457
479
  }
480
+ };
458
481
 
459
- function signal(message) {
460
- return getApi().signal(message, {delegate: true});
482
+ proto._publishEvent = function publishEvent(action, content, msgOpts) {
483
+ const execution = this.execution;
484
+ this.broker.publish('event', `definition.${action}`, execution ? execution._createMessage(content) : cloneContent(content), {
485
+ type: action,
486
+ ...msgOpts,
487
+ });
488
+ };
489
+
490
+ proto._onStop = function onStop() {
491
+ this[stoppedSymbol] = true;
492
+ this._deactivateRunConsumers();
493
+ return this._publishEvent('stop', this._createMessage());
494
+ };
495
+
496
+ proto._onBrokerReturnFn = function onBrokerReturn(message) {
497
+ if (message.properties.type === 'error') {
498
+ this._deactivateRunConsumers();
499
+ const err = makeErrorFromMessage(message);
500
+ throw err;
461
501
  }
502
+ };
462
503
 
463
- function cancelActivity(message) {
464
- return getApi().cancel(message, {delegate: true});
465
- }
504
+ proto._reset = function reset() {
505
+ this[execSymbol].executionId = undefined;
506
+ this._deactivateRunConsumers();
507
+ this.broker.purgeQueue('run-q');
508
+ this.broker.purgeQueue('execution-q');
509
+ };
466
510
 
467
- function sendMessage(message) {
468
- const messageContent = {message};
469
- let messageType = 'message';
470
- const reference = message && message.id && getElementById(message.id);
471
- if (reference && reference.resolve) {
472
- const resolvedReference = reference.resolve(createMessage({message}));
473
- messageType = resolvedReference.messageType || messageType;
474
- messageContent.message = {...message, ...resolvedReference};
475
- }
511
+ proto._debug = function debug(msg) {
512
+ this.logger.debug(`<${this.id}> ${msg}`);
513
+ };
476
514
 
477
- return getApi().sendApiMessage(messageType, messageContent, {delegate: true});
478
- }
515
+ function addConsumerCallbacks(definition, callback) {
516
+ const broker = definition.broker;
517
+ clearConsumers();
479
518
 
480
- function onApiMessage(routingKey, message) {
481
- const messageType = message.properties.type;
519
+ broker.subscribeOnce('event', 'definition.stop', cbLeave, {consumerTag: '_definition-callback-stop'});
520
+ broker.subscribeOnce('event', 'definition.leave', cbLeave, {consumerTag: '_definition-callback-leave'});
521
+ broker.subscribeOnce('event', 'definition.error', cbError, {consumerTag: '_definition-callback-error'});
482
522
 
483
- switch (messageType) {
484
- case 'stop': {
485
- if (execution && !execution.completed) return;
486
- onStop();
487
- break;
488
- }
489
- }
523
+ function cbLeave(_, message) {
524
+ clearConsumers();
525
+ return callback(null, definition.getApi(message));
490
526
  }
491
527
 
492
- function onStop() {
493
- stopped = true;
494
- deactivateRunConsumers();
495
- return publishEvent('stop');
528
+ function cbError(_, message) {
529
+ clearConsumers();
530
+ definition._reset();
531
+ return callback(makeErrorFromMessage(message));
496
532
  }
497
533
 
498
- function reset() {
499
- executionId = undefined;
500
- deactivateRunConsumers();
501
- runQ.purge();
502
- executionQ.purge();
534
+ function clearConsumers() {
535
+ broker.cancel('_definition-callback-stop');
536
+ broker.cancel('_definition-callback-leave');
537
+ broker.cancel('_definition-callback-error');
503
538
  }
504
539
  }