@hotmeshio/hotmesh 0.0.51 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -9
- package/build/index.d.ts +1 -2
- package/build/index.js +1 -3
- package/build/modules/enums.d.ts +8 -3
- package/build/modules/enums.js +16 -8
- package/build/modules/errors.d.ts +98 -18
- package/build/modules/errors.js +90 -33
- package/build/package.json +7 -2
- package/build/services/activities/activity.d.ts +8 -0
- package/build/services/activities/activity.js +65 -16
- package/build/services/activities/await.js +6 -6
- package/build/services/activities/cycle.d.ts +2 -2
- package/build/services/activities/cycle.js +5 -5
- package/build/services/activities/hook.js +4 -4
- package/build/services/activities/interrupt.d.ts +3 -3
- package/build/services/activities/interrupt.js +15 -6
- package/build/services/activities/signal.d.ts +2 -2
- package/build/services/activities/signal.js +4 -4
- package/build/services/activities/trigger.js +12 -3
- package/build/services/activities/worker.js +6 -6
- package/build/services/compiler/deployer.js +33 -5
- package/build/services/compiler/validator.d.ts +2 -0
- package/build/services/compiler/validator.js +5 -1
- package/build/services/durable/client.d.ts +7 -1
- package/build/services/durable/client.js +56 -30
- package/build/services/durable/exporter.d.ts +7 -72
- package/build/services/durable/exporter.js +105 -295
- package/build/services/durable/handle.d.ts +11 -6
- package/build/services/durable/handle.js +59 -46
- package/build/services/durable/index.d.ts +0 -2
- package/build/services/durable/index.js +0 -2
- package/build/services/durable/schemas/factory.d.ts +33 -0
- package/build/services/durable/schemas/factory.js +2356 -0
- package/build/services/durable/search.js +8 -8
- package/build/services/durable/worker.js +117 -25
- package/build/services/durable/workflow.d.ts +46 -43
- package/build/services/durable/workflow.js +273 -277
- package/build/services/engine/index.js +3 -0
- package/build/services/exporter/index.d.ts +2 -4
- package/build/services/exporter/index.js +4 -5
- package/build/services/mapper/index.d.ts +6 -2
- package/build/services/mapper/index.js +6 -2
- package/build/services/pipe/functions/array.d.ts +2 -10
- package/build/services/pipe/functions/array.js +30 -28
- package/build/services/pipe/functions/conditional.d.ts +1 -0
- package/build/services/pipe/functions/conditional.js +3 -0
- package/build/services/pipe/functions/date.d.ts +1 -0
- package/build/services/pipe/functions/date.js +4 -0
- package/build/services/pipe/functions/index.d.ts +2 -0
- package/build/services/pipe/functions/index.js +2 -0
- package/build/services/pipe/functions/logical.d.ts +5 -0
- package/build/services/pipe/functions/logical.js +12 -0
- package/build/services/pipe/functions/object.d.ts +3 -0
- package/build/services/pipe/functions/object.js +25 -7
- package/build/services/pipe/index.d.ts +20 -3
- package/build/services/pipe/index.js +82 -16
- package/build/services/router/index.js +14 -3
- package/build/services/serializer/index.d.ts +3 -2
- package/build/services/serializer/index.js +11 -4
- package/build/services/store/clients/ioredis.js +6 -6
- package/build/services/store/clients/redis.js +7 -7
- package/build/services/store/index.d.ts +2 -0
- package/build/services/store/index.js +4 -1
- package/build/services/stream/clients/ioredis.js +8 -8
- package/build/services/stream/clients/redis.js +1 -1
- package/build/types/activity.d.ts +60 -5
- package/build/types/durable.d.ts +168 -33
- package/build/types/exporter.d.ts +26 -4
- package/build/types/index.d.ts +2 -2
- package/build/types/job.d.ts +69 -5
- package/build/types/pipe.d.ts +81 -3
- package/build/types/stream.d.ts +61 -1
- package/build/types/stream.js +4 -0
- package/index.ts +1 -2
- package/modules/enums.ts +16 -8
- package/modules/errors.ts +174 -32
- package/package.json +7 -2
- package/services/activities/activity.ts +67 -18
- package/services/activities/await.ts +6 -6
- package/services/activities/cycle.ts +7 -6
- package/services/activities/hook.ts +4 -4
- package/services/activities/interrupt.ts +19 -9
- package/services/activities/signal.ts +6 -5
- package/services/activities/trigger.ts +16 -4
- package/services/activities/worker.ts +7 -7
- package/services/compiler/deployer.ts +33 -6
- package/services/compiler/validator.ts +7 -3
- package/services/durable/client.ts +47 -14
- package/services/durable/exporter.ts +110 -318
- package/services/durable/handle.ts +63 -50
- package/services/durable/index.ts +0 -2
- package/services/durable/schemas/factory.ts +2358 -0
- package/services/durable/search.ts +8 -8
- package/services/durable/worker.ts +128 -29
- package/services/durable/workflow.ts +304 -288
- package/services/engine/index.ts +4 -0
- package/services/exporter/index.ts +10 -12
- package/services/mapper/index.ts +6 -2
- package/services/pipe/functions/array.ts +24 -37
- package/services/pipe/functions/conditional.ts +4 -0
- package/services/pipe/functions/date.ts +6 -0
- package/services/pipe/functions/index.ts +7 -5
- package/services/pipe/functions/logical.ts +11 -0
- package/services/pipe/functions/object.ts +26 -7
- package/services/pipe/index.ts +99 -21
- package/services/quorum/index.ts +1 -3
- package/services/router/index.ts +14 -3
- package/services/serializer/index.ts +12 -5
- package/services/store/clients/ioredis.ts +6 -6
- package/services/store/clients/redis.ts +7 -7
- package/services/store/index.ts +4 -1
- package/services/stream/clients/ioredis.ts +8 -8
- package/services/stream/clients/redis.ts +1 -1
- package/types/activity.ts +87 -15
- package/types/durable.ts +246 -73
- package/types/exporter.ts +31 -5
- package/types/index.ts +6 -7
- package/types/job.ts +130 -36
- package/types/pipe.ts +84 -3
- package/types/stream.ts +82 -23
- package/build/services/durable/factory.d.ts +0 -17
- package/build/services/durable/factory.js +0 -817
- package/build/services/durable/meshos.d.ts +0 -127
- package/build/services/durable/meshos.js +0 -380
- package/services/durable/factory.ts +0 -818
- package/services/durable/meshos.ts +0 -441
|
@@ -83,22 +83,22 @@ class Activity {
|
|
|
83
83
|
}
|
|
84
84
|
catch (error) {
|
|
85
85
|
if (error instanceof errors_1.CollationError) {
|
|
86
|
-
this.logger.info('process-event-inactive-error', { error });
|
|
86
|
+
this.logger.info('process-event-inactive-error', { ...error });
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
else if (error instanceof errors_1.InactiveJobError) {
|
|
90
|
-
this.logger.info('process-event-inactive-job-error', { error });
|
|
90
|
+
this.logger.info('process-event-inactive-job-error', { ...error });
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
93
|
else if (error instanceof errors_1.GenerationalError) {
|
|
94
|
-
this.logger.info('process-event-generational-job-error', { error });
|
|
94
|
+
this.logger.info('process-event-generational-job-error', { ...error });
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
97
|
else if (error instanceof errors_1.GetStateError) {
|
|
98
|
-
this.logger.info('process-event-get-job-error', { error });
|
|
98
|
+
this.logger.info('process-event-get-job-error', { ...error });
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
|
-
this.logger.error('activity-process-event-error', { error });
|
|
101
|
+
this.logger.error('activity-process-event-error', { ...error, message: error.message, stack: error.stack, name: error.name });
|
|
102
102
|
telemetry && telemetry.setActivityError(error.message);
|
|
103
103
|
throw error;
|
|
104
104
|
}
|
|
@@ -130,6 +130,10 @@ class Activity {
|
|
|
130
130
|
async processError(telemetry, type) {
|
|
131
131
|
this.bindActivityError(this.data);
|
|
132
132
|
this.adjacencyList = await this.filterAdjacent();
|
|
133
|
+
if (!this.adjacencyList.length) {
|
|
134
|
+
this.bindJobError(this.data);
|
|
135
|
+
}
|
|
136
|
+
this.mapJobData();
|
|
133
137
|
const multi = this.store.getMulti();
|
|
134
138
|
await this.setState(multi);
|
|
135
139
|
await collator_1.CollatorService.notarizeCompletion(this, multi);
|
|
@@ -142,7 +146,7 @@ class Activity {
|
|
|
142
146
|
const attrs = { 'app.job.jss': jobStatus };
|
|
143
147
|
//adjacencyList membership has already been set at this point (according to activity status)
|
|
144
148
|
const messageIds = await this.transition(this.adjacencyList, jobStatus);
|
|
145
|
-
if (messageIds
|
|
149
|
+
if (messageIds?.length) {
|
|
146
150
|
attrs['app.activity.mids'] = messageIds.join(',');
|
|
147
151
|
}
|
|
148
152
|
telemetry.setActivityAttributes(attrs);
|
|
@@ -159,7 +163,31 @@ class Activity {
|
|
|
159
163
|
mapJobData() {
|
|
160
164
|
if (this.config.job?.maps) {
|
|
161
165
|
const mapper = new mapper_1.MapperService(this.config.job.maps, this.context);
|
|
162
|
-
|
|
166
|
+
const output = mapper.mapRules();
|
|
167
|
+
if (output) {
|
|
168
|
+
for (const key in output) {
|
|
169
|
+
const f1 = key.indexOf('[');
|
|
170
|
+
//keys with array notation suffix `somekey[]` represent
|
|
171
|
+
//dynamically-keyed mappings whose `value` must be moved to the output.
|
|
172
|
+
//The `value` must be an object with keys appropriate to the
|
|
173
|
+
//notation type: `somekey[0] (array)`, `somekey[-] (mark)`, OR `somekey[_] (search)`
|
|
174
|
+
if (f1 > -1) {
|
|
175
|
+
const amount = key.substring(f1 + 1).split(']')[0];
|
|
176
|
+
if (!isNaN(Number(amount))) {
|
|
177
|
+
const left = key.substring(0, f1);
|
|
178
|
+
output[left] = output[key];
|
|
179
|
+
delete output[key];
|
|
180
|
+
}
|
|
181
|
+
else if (amount === '-' || amount === '_') {
|
|
182
|
+
const obj = output[key];
|
|
183
|
+
Object.keys(obj).forEach((newKey) => {
|
|
184
|
+
output[newKey] = obj[newKey];
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
this.context.data = output;
|
|
163
191
|
}
|
|
164
192
|
}
|
|
165
193
|
mapInputData() {
|
|
@@ -181,10 +209,21 @@ class Activity {
|
|
|
181
209
|
async registerTimeout() {
|
|
182
210
|
//set timeout in support of hook and/or duplex
|
|
183
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Any StreamMessage with a status of ERROR is bound to the activity
|
|
214
|
+
*/
|
|
184
215
|
bindActivityError(data) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
216
|
+
const md = this.context[this.metadata.aid].output.metadata;
|
|
217
|
+
md.err = JSON.stringify(this.data);
|
|
218
|
+
//(temporary...useful for mapping error parts in the app.yaml)
|
|
219
|
+
md.$error = { ...data, is_stream_error: true };
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* unhandled activity errors (activities that return an ERROR StreamMessage
|
|
223
|
+
* status and have no adjacent children to transition to) are bound to the job
|
|
224
|
+
*/
|
|
225
|
+
bindJobError(data) {
|
|
226
|
+
this.context.metadata.err = JSON.stringify({ ...data, is_stream_error: true });
|
|
188
227
|
}
|
|
189
228
|
async getTriggerConfig() {
|
|
190
229
|
return await this.store.getSchema(this.config.trigger, await this.engine.getVID());
|
|
@@ -238,9 +277,9 @@ class Activity {
|
|
|
238
277
|
if (this.status === stream_1.StreamStatus.ERROR) {
|
|
239
278
|
self.output.metadata.err = JSON.stringify(this.data);
|
|
240
279
|
}
|
|
241
|
-
|
|
242
|
-
self.output.metadata.ac =
|
|
243
|
-
|
|
280
|
+
const ts = (0, utils_1.formatISODate)(new Date());
|
|
281
|
+
self.output.metadata.ac = ts;
|
|
282
|
+
self.output.metadata.au = ts;
|
|
244
283
|
self.output.metadata.atp = this.config.type;
|
|
245
284
|
if (this.config.subtype) {
|
|
246
285
|
self.output.metadata.stp = this.config.subtype;
|
|
@@ -259,6 +298,11 @@ class Activity {
|
|
|
259
298
|
state[path] = value;
|
|
260
299
|
}
|
|
261
300
|
}
|
|
301
|
+
for (let key in this.context?.data ?? {}) {
|
|
302
|
+
if (key.startsWith('-') || key.startsWith('_')) {
|
|
303
|
+
state[key] = this.context.data[key];
|
|
304
|
+
}
|
|
305
|
+
}
|
|
262
306
|
telemetry_1.TelemetryService.bindJobTelemetryToState(state, this.config, this.context);
|
|
263
307
|
}
|
|
264
308
|
bindActivityState(state) {
|
|
@@ -310,9 +354,9 @@ class Activity {
|
|
|
310
354
|
let { dad, jid } = this.context.metadata;
|
|
311
355
|
const dIds = collator_1.CollatorService.getDimensionsById([...this.config.ancestors, this.metadata.aid], dad || '');
|
|
312
356
|
//`state` is a unidimensional hash; context is a tree
|
|
313
|
-
const [state,
|
|
357
|
+
const [state, _status] = await this.store.getState(jid, consumes, dIds);
|
|
314
358
|
this.context = (0, utils_1.restoreHierarchy)(state);
|
|
315
|
-
this.assertGenerationalId(this.context
|
|
359
|
+
this.assertGenerationalId(this.context?.metadata?.gid, gid);
|
|
316
360
|
this.initDimensionalAddress(dad);
|
|
317
361
|
this.initSelf(this.context);
|
|
318
362
|
this.initPolicies(this.context);
|
|
@@ -325,7 +369,7 @@ class Activity {
|
|
|
325
369
|
*/
|
|
326
370
|
assertGenerationalId(jobGID, msgGID) {
|
|
327
371
|
if (msgGID !== jobGID) {
|
|
328
|
-
throw new errors_1.GenerationalError(jobGID, msgGID, this.context
|
|
372
|
+
throw new errors_1.GenerationalError(jobGID, msgGID, this.context?.metadata?.jid ?? '', this.context?.metadata?.aid ?? '', this.context?.metadata?.dad ?? '');
|
|
329
373
|
}
|
|
330
374
|
}
|
|
331
375
|
initDimensionalAddress(dad) {
|
|
@@ -346,6 +390,11 @@ class Activity {
|
|
|
346
390
|
if (!self.hook) {
|
|
347
391
|
self.hook = {};
|
|
348
392
|
}
|
|
393
|
+
if (!self.output.metadata) {
|
|
394
|
+
self.output.metadata = {};
|
|
395
|
+
}
|
|
396
|
+
//prebind the updated timestamp (mappings need the time)
|
|
397
|
+
self.output.metadata.au = (0, utils_1.formatISODate)(new Date());
|
|
349
398
|
context['$self'] = self;
|
|
350
399
|
context['$job'] = context; //NEVER call STRINGIFY! (now circular)
|
|
351
400
|
return context;
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Await = void 0;
|
|
4
4
|
const errors_1 = require("../../modules/errors");
|
|
5
|
+
const utils_1 = require("../../modules/utils");
|
|
5
6
|
const activity_1 = require("./activity");
|
|
6
7
|
const collator_1 = require("../collator");
|
|
8
|
+
const pipe_1 = require("../pipe");
|
|
7
9
|
const telemetry_1 = require("../telemetry");
|
|
8
10
|
const stream_1 = require("../../types/stream");
|
|
9
|
-
const pipe_1 = require("../pipe");
|
|
10
|
-
const utils_1 = require("../../modules/utils");
|
|
11
11
|
class Await extends activity_1.Activity {
|
|
12
12
|
constructor(config, data, metadata, hook, engine, context) {
|
|
13
13
|
super(config, data, metadata, hook, engine, context);
|
|
@@ -40,19 +40,19 @@ class Await extends activity_1.Activity {
|
|
|
40
40
|
}
|
|
41
41
|
catch (error) {
|
|
42
42
|
if (error instanceof errors_1.InactiveJobError) {
|
|
43
|
-
this.logger.error('await-inactive-job-error', { error });
|
|
43
|
+
this.logger.error('await-inactive-job-error', { ...error });
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
else if (error instanceof errors_1.GenerationalError) {
|
|
47
|
-
this.logger.info('process-event-generational-job-error', { error });
|
|
47
|
+
this.logger.info('process-event-generational-job-error', { ...error });
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
else if (error instanceof errors_1.GetStateError) {
|
|
51
|
-
this.logger.error('await-get-state-error', { error });
|
|
51
|
+
this.logger.error('await-get-state-error', { ...error });
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
55
|
-
this.logger.error('await-process-error', { error });
|
|
55
|
+
this.logger.error('await-process-error', { ...error });
|
|
56
56
|
}
|
|
57
57
|
telemetry.setActivityError(error.message);
|
|
58
58
|
throw error;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EngineService } from '../engine';
|
|
2
|
-
import { Activity
|
|
3
|
-
import { ActivityData, ActivityMetadata, CycleActivity } from '../../types/activity';
|
|
2
|
+
import { Activity } from './activity';
|
|
3
|
+
import { ActivityData, ActivityMetadata, ActivityType, CycleActivity } from '../../types/activity';
|
|
4
4
|
import { JobState } from '../../types/job';
|
|
5
5
|
import { RedisMulti } from '../../types/redis';
|
|
6
6
|
declare class Cycle extends Activity {
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Cycle = void 0;
|
|
4
4
|
const errors_1 = require("../../modules/errors");
|
|
5
|
+
const utils_1 = require("../../modules/utils");
|
|
5
6
|
const collator_1 = require("../collator");
|
|
6
7
|
const activity_1 = require("./activity");
|
|
7
8
|
const telemetry_1 = require("../telemetry");
|
|
8
|
-
const utils_1 = require("../../modules/utils");
|
|
9
9
|
class Cycle extends activity_1.Activity {
|
|
10
10
|
constructor(config, data, metadata, hook, engine, context) {
|
|
11
11
|
super(config, data, metadata, hook, engine, context);
|
|
@@ -40,19 +40,19 @@ class Cycle extends activity_1.Activity {
|
|
|
40
40
|
}
|
|
41
41
|
catch (error) {
|
|
42
42
|
if (error instanceof errors_1.InactiveJobError) {
|
|
43
|
-
this.logger.error('cycle-inactive-job-error', { error });
|
|
43
|
+
this.logger.error('cycle-inactive-job-error', { ...error });
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
else if (error instanceof errors_1.GenerationalError) {
|
|
47
|
-
this.logger.info('process-event-generational-job-error', { error });
|
|
47
|
+
this.logger.info('process-event-generational-job-error', { ...error });
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
else if (error instanceof errors_1.GetStateError) {
|
|
51
|
-
this.logger.error('cycle-get-state-error', { error });
|
|
51
|
+
this.logger.error('cycle-get-state-error', { ...error });
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
55
|
-
this.logger.error('cycle-process-error', { error });
|
|
55
|
+
this.logger.error('cycle-process-error', { ...error });
|
|
56
56
|
}
|
|
57
57
|
telemetry.setActivityError(error.message);
|
|
58
58
|
throw error;
|
|
@@ -39,19 +39,19 @@ class Hook extends activity_1.Activity {
|
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
41
|
if (error instanceof errors_1.InactiveJobError) {
|
|
42
|
-
this.logger.error('hook-inactive-job-error', { error });
|
|
42
|
+
this.logger.error('hook-inactive-job-error', { ...error });
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
else if (error instanceof errors_1.GenerationalError) {
|
|
46
|
-
this.logger.info('process-event-generational-job-error', { error });
|
|
46
|
+
this.logger.info('process-event-generational-job-error', { ...error });
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
else if (error instanceof errors_1.GetStateError) {
|
|
50
|
-
this.logger.error('hook-get-state-error', { error });
|
|
50
|
+
this.logger.error('hook-get-state-error', { ...error });
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
this.logger.error('hook-process-error', { error });
|
|
54
|
+
this.logger.error('hook-process-error', { ...error });
|
|
55
55
|
}
|
|
56
56
|
telemetry.setActivityError(error.message);
|
|
57
57
|
throw error;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { Activity } from './activity';
|
|
1
2
|
import { EngineService } from '../engine';
|
|
2
|
-
import { Activity, ActivityType } from './activity';
|
|
3
|
-
import { ActivityData, ActivityMetadata, InterruptActivity } from '../../types/activity';
|
|
4
|
-
import { JobInterruptOptions, JobState } from '../../types/job';
|
|
5
3
|
import { TelemetryService } from '../telemetry';
|
|
4
|
+
import { ActivityData, ActivityMetadata, ActivityType, InterruptActivity } from '../../types/activity';
|
|
5
|
+
import { JobInterruptOptions, JobState } from '../../types/job';
|
|
6
6
|
declare class Interrupt extends Activity {
|
|
7
7
|
config: InterruptActivity;
|
|
8
8
|
constructor(config: ActivityType, data: ActivityData, metadata: ActivityMetadata, hook: ActivityData | null, engine: EngineService, context?: JobState);
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Interrupt = void 0;
|
|
4
4
|
const errors_1 = require("../../modules/errors");
|
|
5
|
-
const activity_1 = require("./activity");
|
|
6
5
|
const collator_1 = require("../collator");
|
|
7
|
-
const
|
|
6
|
+
const activity_1 = require("./activity");
|
|
8
7
|
const pipe_1 = require("../pipe");
|
|
8
|
+
const telemetry_1 = require("../telemetry");
|
|
9
9
|
class Interrupt extends activity_1.Activity {
|
|
10
10
|
constructor(config, data, metadata, hook, engine, context) {
|
|
11
11
|
super(config, data, metadata, hook, engine, context);
|
|
@@ -27,19 +27,19 @@ class Interrupt extends activity_1.Activity {
|
|
|
27
27
|
}
|
|
28
28
|
catch (error) {
|
|
29
29
|
if (error instanceof errors_1.InactiveJobError) {
|
|
30
|
-
this.logger.error('interrupt-inactive-job-error', { error });
|
|
30
|
+
this.logger.error('interrupt-inactive-job-error', { ...error });
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
else if (error instanceof errors_1.GenerationalError) {
|
|
34
|
-
this.logger.info('process-event-generational-job-error', { error });
|
|
34
|
+
this.logger.info('process-event-generational-job-error', { ...error });
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
else if (error instanceof errors_1.GetStateError) {
|
|
38
|
-
this.logger.error('interrupt-get-state-error', { error });
|
|
38
|
+
this.logger.error('interrupt-get-state-error', { ...error });
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
else {
|
|
42
|
-
this.logger.error('interrupt-process-error', { error });
|
|
42
|
+
this.logger.error('interrupt-process-error', { ...error });
|
|
43
43
|
}
|
|
44
44
|
telemetry.setActivityError(error.message);
|
|
45
45
|
throw error;
|
|
@@ -116,6 +116,15 @@ class Interrupt extends activity_1.Activity {
|
|
|
116
116
|
descend: this.config.descend !== undefined
|
|
117
117
|
? pipe_1.Pipe.resolve(this.config.descend, this.context)
|
|
118
118
|
: undefined,
|
|
119
|
+
code: this.config.code !== undefined
|
|
120
|
+
? pipe_1.Pipe.resolve(this.config.code, this.context)
|
|
121
|
+
: undefined,
|
|
122
|
+
expire: this.config.expire !== undefined
|
|
123
|
+
? pipe_1.Pipe.resolve(this.config.expire, this.context)
|
|
124
|
+
: undefined,
|
|
125
|
+
stack: this.config.stack !== undefined
|
|
126
|
+
? pipe_1.Pipe.resolve(this.config.stack, this.context)
|
|
127
|
+
: undefined,
|
|
119
128
|
};
|
|
120
129
|
}
|
|
121
130
|
async interrupt() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Activity
|
|
1
|
+
import { Activity } from './activity';
|
|
2
2
|
import { EngineService } from '../engine';
|
|
3
|
-
import { ActivityData, ActivityMetadata, SignalActivity } from '../../types/activity';
|
|
3
|
+
import { ActivityData, ActivityMetadata, ActivityType, SignalActivity } from '../../types/activity';
|
|
4
4
|
import { JobState } from '../../types/job';
|
|
5
5
|
declare class Signal extends Activity {
|
|
6
6
|
config: SignalActivity;
|
|
@@ -48,19 +48,19 @@ class Signal extends activity_1.Activity {
|
|
|
48
48
|
}
|
|
49
49
|
catch (error) {
|
|
50
50
|
if (error instanceof errors_1.InactiveJobError) {
|
|
51
|
-
this.logger.error('signal-inactive-job-error', { error });
|
|
51
|
+
this.logger.error('signal-inactive-job-error', { ...error });
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
else if (error instanceof errors_1.GenerationalError) {
|
|
55
|
-
this.logger.info('process-event-generational-job-error', { error });
|
|
55
|
+
this.logger.info('process-event-generational-job-error', { ...error });
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
else if (error instanceof errors_1.GetStateError) {
|
|
59
|
-
this.logger.error('signal-get-state-error', { error });
|
|
59
|
+
this.logger.error('signal-get-state-error', { ...error });
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
else {
|
|
63
|
-
this.logger.error('signal-process-error', { error });
|
|
63
|
+
this.logger.error('signal-process-error', { ...error });
|
|
64
64
|
}
|
|
65
65
|
telemetry.setActivityError(error.message);
|
|
66
66
|
throw error;
|
|
@@ -47,10 +47,10 @@ class Trigger extends activity_1.Activity {
|
|
|
47
47
|
}
|
|
48
48
|
catch (error) {
|
|
49
49
|
if (error instanceof errors_1.DuplicateJobError) {
|
|
50
|
-
this.logger.error('duplicate-job-error', { error });
|
|
50
|
+
this.logger.error('duplicate-job-error', { job_id: error.jobId });
|
|
51
51
|
}
|
|
52
52
|
else {
|
|
53
|
-
this.logger.error('trigger-process-error', { error });
|
|
53
|
+
this.logger.error('trigger-process-error', { ...error });
|
|
54
54
|
}
|
|
55
55
|
telemetry.setActivityError(error.message);
|
|
56
56
|
throw error;
|
|
@@ -66,7 +66,16 @@ class Trigger extends activity_1.Activity {
|
|
|
66
66
|
}
|
|
67
67
|
async execAdjacentParent() {
|
|
68
68
|
if (this.context.metadata.px) {
|
|
69
|
-
|
|
69
|
+
const timestamp = (0, utils_1.formatISODate)(new Date());
|
|
70
|
+
const jobStartedConfirmationMessage = {
|
|
71
|
+
metadata: this.context.metadata,
|
|
72
|
+
data: {
|
|
73
|
+
job_id: this.context.metadata.jid,
|
|
74
|
+
jc: timestamp,
|
|
75
|
+
ju: timestamp,
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
await this.engine.execAdjacentParent(this.context, jobStartedConfirmationMessage);
|
|
70
79
|
}
|
|
71
80
|
}
|
|
72
81
|
createInputContext() {
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Worker = void 0;
|
|
4
4
|
const errors_1 = require("../../modules/errors");
|
|
5
|
+
const utils_1 = require("../../modules/utils");
|
|
5
6
|
const activity_1 = require("./activity");
|
|
6
7
|
const collator_1 = require("../collator");
|
|
7
|
-
const telemetry_1 = require("../telemetry");
|
|
8
8
|
const pipe_1 = require("../pipe");
|
|
9
|
-
const
|
|
9
|
+
const telemetry_1 = require("../telemetry");
|
|
10
10
|
class Worker extends activity_1.Activity {
|
|
11
11
|
constructor(config, data, metadata, hook, engine, context) {
|
|
12
12
|
super(config, data, metadata, hook, engine, context);
|
|
@@ -39,19 +39,19 @@ class Worker extends activity_1.Activity {
|
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
41
|
if (error instanceof errors_1.InactiveJobError) {
|
|
42
|
-
this.logger.error('await-inactive-job-error', { error });
|
|
42
|
+
this.logger.error('await-inactive-job-error', { ...error });
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
else if (error instanceof errors_1.GenerationalError) {
|
|
46
|
-
this.logger.info('process-event-generational-job-error', { error });
|
|
46
|
+
this.logger.info('process-event-generational-job-error', { ...error });
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
else if (error instanceof errors_1.GetStateError) {
|
|
50
|
-
this.logger.error('worker-get-state-error', { error });
|
|
50
|
+
this.logger.error('worker-get-state-error', { ...error });
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
this.logger.error('worker-process-error', { error });
|
|
54
|
+
this.logger.error('worker-process-error', { ...error });
|
|
55
55
|
}
|
|
56
56
|
telemetry.setActivityError(error.message);
|
|
57
57
|
throw error;
|
|
@@ -6,6 +6,7 @@ const utils_1 = require("../../modules/utils");
|
|
|
6
6
|
const collator_1 = require("../collator");
|
|
7
7
|
const serializer_1 = require("../serializer");
|
|
8
8
|
const pipe_1 = require("../pipe");
|
|
9
|
+
const validator_1 = require("./validator");
|
|
9
10
|
const DEFAULT_METADATA_RANGE_SIZE = 26; //metadata is 26 slots ([a-z] * 1)
|
|
10
11
|
const DEFAULT_DATA_RANGE_SIZE = 260; //data is 260 slots ([a-zA-Z] * 5)
|
|
11
12
|
const DEFAULT_RANGE_SIZE = DEFAULT_METADATA_RANGE_SIZE + DEFAULT_DATA_RANGE_SIZE;
|
|
@@ -185,6 +186,9 @@ class Deployer {
|
|
|
185
186
|
//DAGs have one parent; easy to optimize for
|
|
186
187
|
graph.activities[to].parent = fromActivity;
|
|
187
188
|
}
|
|
189
|
+
//temporarily bind the transitions to the parent activity,
|
|
190
|
+
// so the consumer/producer registrar picks up the bindings
|
|
191
|
+
graph.activities[fromActivity].transitions = toTransitions;
|
|
188
192
|
}
|
|
189
193
|
}
|
|
190
194
|
}
|
|
@@ -241,9 +245,30 @@ class Deployer {
|
|
|
241
245
|
traverse(obj[key], newPath);
|
|
242
246
|
}
|
|
243
247
|
else {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
248
|
+
//wildcard mapping (e.g., 'friends[25]')
|
|
249
|
+
//when this is resolved, it will be expanded to
|
|
250
|
+
//`'friends/0', ..., 'friends/24'`, providing 25 dynamic
|
|
251
|
+
//slots in the flow's output data
|
|
252
|
+
const pathName = [...path, key].join('/');
|
|
253
|
+
if (!pathName.includes('[')) {
|
|
254
|
+
const finalPath = `data/${pathName}`;
|
|
255
|
+
if (!result.includes(finalPath)) {
|
|
256
|
+
result.push(finalPath);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
const [left, right] = pathName.split('[');
|
|
261
|
+
//check if this variable isLiteralKeyType (#, -, or _)
|
|
262
|
+
const [amount, _] = right.split(']');
|
|
263
|
+
if (!isNaN(parseInt(amount))) {
|
|
264
|
+
//loop to create all possible paths (0 to amount)
|
|
265
|
+
for (let i = 0; i < parseInt(amount); i++) {
|
|
266
|
+
const finalPath = `data/${left}/${i}`;
|
|
267
|
+
if (!result.includes(finalPath)) {
|
|
268
|
+
result.push(finalPath);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
} //else ignore (amount might be '-' or '_') `-` is marker data; `_` is job data;
|
|
247
272
|
}
|
|
248
273
|
}
|
|
249
274
|
}
|
|
@@ -271,7 +296,7 @@ class Deployer {
|
|
|
271
296
|
if (typeof obj[key] === 'string') {
|
|
272
297
|
const stringValue = obj[key];
|
|
273
298
|
const dynamicMappingRuleMatch = stringValue.match(/^\{[^@].*}$/);
|
|
274
|
-
if (dynamicMappingRuleMatch) {
|
|
299
|
+
if (dynamicMappingRuleMatch && !validator_1.Validator.CONTEXT_VARS.includes(stringValue)) {
|
|
275
300
|
if (stringValue.split('.')[1] !== 'input') {
|
|
276
301
|
dynamicMappingRules.push(stringValue);
|
|
277
302
|
consumes.push(stringValue);
|
|
@@ -340,7 +365,10 @@ class Deployer {
|
|
|
340
365
|
for (const graph of graphs) {
|
|
341
366
|
const activities = graph.activities;
|
|
342
367
|
for (const activityKey in activities) {
|
|
343
|
-
|
|
368
|
+
const target = activities[activityKey];
|
|
369
|
+
//remove transitions; no longer necessary for runtime
|
|
370
|
+
delete target.transitions;
|
|
371
|
+
activitySchemas[activityKey] = target;
|
|
344
372
|
}
|
|
345
373
|
}
|
|
346
374
|
await this.store.setSchemas(activitySchemas, this.getVID());
|
|
@@ -8,6 +8,7 @@ declare class Validator {
|
|
|
8
8
|
mappingStatements: MappingStatements;
|
|
9
9
|
store: StoreService<RedisClient, RedisMulti> | null;
|
|
10
10
|
static SYS_VARS: string[];
|
|
11
|
+
static CONTEXT_VARS: string[];
|
|
11
12
|
constructor(manifest: HotMeshManifest);
|
|
12
13
|
/**
|
|
13
14
|
* validate the manifest file
|
|
@@ -19,6 +20,7 @@ declare class Validator {
|
|
|
19
20
|
getMappingStatements(): void;
|
|
20
21
|
validateReferencedActivityIds(): void;
|
|
21
22
|
isFunction(value: string): boolean;
|
|
23
|
+
isContextVariable(value: string): boolean;
|
|
22
24
|
validateMappingStatements(): void;
|
|
23
25
|
validateTransitions(): void;
|
|
24
26
|
validateTransitionConditions(): void;
|
|
@@ -83,7 +83,7 @@ class Validator {
|
|
|
83
83
|
if (statement.startsWith('{') && statement.endsWith('}')) {
|
|
84
84
|
const statementParts = statement.slice(1, -1).split('.');
|
|
85
85
|
const referencedActivityId = statementParts[0];
|
|
86
|
-
if (!(Validator.SYS_VARS.includes(referencedActivityId) || activityIds.includes(referencedActivityId) || this.isFunction(statement))) {
|
|
86
|
+
if (!(Validator.SYS_VARS.includes(referencedActivityId) || activityIds.includes(referencedActivityId) || this.isFunction(statement) || this.isContextVariable(statement))) {
|
|
87
87
|
throw new Error(`Mapping statement references non-existent activity: ${statement}`);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
@@ -93,6 +93,9 @@ class Validator {
|
|
|
93
93
|
isFunction(value) {
|
|
94
94
|
return value.startsWith('{@') && pipe_1.Pipe.resolveFunction(value);
|
|
95
95
|
}
|
|
96
|
+
isContextVariable(value) {
|
|
97
|
+
return ['{$input}', '{$output}', '{$item}', '{$key}', '{$index}'].includes(value);
|
|
98
|
+
}
|
|
96
99
|
// 1.3) Validate the mapping/@pipe statements are valid
|
|
97
100
|
validateMappingStatements() {
|
|
98
101
|
// Implement the method content
|
|
@@ -132,3 +135,4 @@ class Validator {
|
|
|
132
135
|
}
|
|
133
136
|
exports.Validator = Validator;
|
|
134
137
|
Validator.SYS_VARS = ['$app', '$self', '$graph', '$job'];
|
|
138
|
+
Validator.CONTEXT_VARS = ['{$input}', '{$output}', '{$item}', '{$key}', '{$index}'];
|
|
@@ -14,7 +14,13 @@ export declare class ClientService {
|
|
|
14
14
|
* has not yet been initialized, so this call ensures that the channel
|
|
15
15
|
* exists and is ready to serve as a container for events.
|
|
16
16
|
*/
|
|
17
|
-
createStream: (hotMeshClient: HotMesh, workflowTopic: string, namespace?: string) => Promise<void>;
|
|
17
|
+
static createStream: (hotMeshClient: HotMesh, workflowTopic: string, namespace?: string) => Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* It is possible for a client to invoke a workflow without first
|
|
20
|
+
* creating the stream. This method will verify that the stream
|
|
21
|
+
* exists and if not, create it.
|
|
22
|
+
*/
|
|
23
|
+
static verifyStream: (workflowTopic: string, namespace?: string) => Promise<HotMesh>;
|
|
18
24
|
/**
|
|
19
25
|
* For those deployments with a redis stack backend (with the FT module),
|
|
20
26
|
* this method will configure the search index for the workflow.
|