@hotmeshio/hotmesh 0.0.36 → 0.0.38
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 +11 -11
- package/build/modules/enums.d.ts +1 -0
- package/build/modules/enums.js +3 -1
- package/build/modules/errors.d.ts +9 -1
- package/build/modules/errors.js +12 -1
- package/build/modules/key.d.ts +20 -19
- package/build/modules/key.js +20 -20
- package/build/package.json +1 -1
- package/build/services/activities/activity.d.ts +10 -0
- package/build/services/activities/activity.js +28 -3
- package/build/services/activities/await.js +10 -9
- package/build/services/activities/cycle.js +10 -9
- package/build/services/activities/hook.d.ts +7 -1
- package/build/services/activities/hook.js +61 -44
- package/build/services/activities/interrupt.js +10 -9
- package/build/services/activities/signal.js +7 -7
- package/build/services/activities/trigger.js +4 -2
- package/build/services/activities/worker.js +9 -8
- package/build/services/durable/meshos.js +2 -2
- package/build/services/durable/worker.js +2 -2
- package/build/services/durable/workflow.js +17 -17
- package/build/services/engine/index.d.ts +5 -7
- package/build/services/engine/index.js +53 -47
- package/build/services/hotmesh/index.d.ts +2 -2
- package/build/services/hotmesh/index.js +6 -7
- package/build/services/quorum/index.d.ts +6 -6
- package/build/services/quorum/index.js +47 -11
- package/build/services/{signaler/stream.d.ts → router/index.d.ts} +3 -3
- package/build/services/{signaler/stream.js → router/index.js} +6 -6
- package/build/services/serializer/index.js +1 -1
- package/build/services/store/clients/ioredis.d.ts +1 -0
- package/build/services/store/clients/ioredis.js +9 -0
- package/build/services/store/clients/redis.d.ts +1 -0
- package/build/services/store/clients/redis.js +16 -0
- package/build/services/store/index.d.ts +10 -4
- package/build/services/store/index.js +21 -10
- package/build/services/stream/clients/ioredis.d.ts +1 -0
- package/build/services/stream/clients/ioredis.js +33 -24
- package/build/services/stream/clients/redis.d.ts +1 -0
- package/build/services/stream/clients/redis.js +15 -0
- package/build/services/stream/index.d.ts +1 -0
- package/build/services/task/index.d.ts +13 -4
- package/build/services/task/index.js +115 -17
- package/build/services/telemetry/index.js +6 -6
- package/build/services/worker/index.d.ts +4 -3
- package/build/services/worker/index.js +32 -8
- package/build/types/job.d.ts +2 -0
- package/build/types/quorum.d.ts +11 -1
- package/build/types/redisclient.d.ts +1 -0
- package/build/types/stream.d.ts +1 -0
- package/modules/enums.ts +3 -0
- package/modules/errors.ts +18 -0
- package/modules/key.ts +21 -20
- package/package.json +1 -1
- package/services/activities/activity.ts +44 -4
- package/services/activities/await.ts +14 -10
- package/services/activities/cycle.ts +14 -10
- package/services/activities/hook.ts +70 -47
- package/services/activities/interrupt.ts +13 -10
- package/services/activities/signal.ts +11 -8
- package/services/activities/trigger.ts +5 -1
- package/services/activities/worker.ts +13 -9
- package/services/durable/meshos.ts +1 -1
- package/services/durable/worker.ts +1 -1
- package/services/durable/workflow.ts +1 -1
- package/services/engine/index.ts +82 -44
- package/services/hotmesh/index.ts +7 -8
- package/services/quorum/index.ts +48 -12
- package/services/{signaler/stream.ts → router/index.ts} +5 -5
- package/services/serializer/index.ts +1 -1
- package/services/store/clients/ioredis.ts +9 -0
- package/services/store/clients/redis.ts +16 -0
- package/services/store/index.ts +27 -12
- package/services/stream/clients/ioredis.ts +33 -24
- package/services/stream/clients/redis.ts +14 -0
- package/services/stream/index.ts +1 -0
- package/services/task/index.ts +120 -21
- package/services/telemetry/index.ts +6 -6
- package/services/worker/index.ts +37 -7
- package/types/job.ts +2 -0
- package/types/quorum.ts +15 -4
- package/types/redisclient.ts +1 -0
- package/types/stream.ts +6 -5
- package/build/services/signaler/store.d.ts +0 -15
- package/build/services/signaler/store.js +0 -68
- package/services/signaler/store.ts +0 -76
- /package/build/{services/durable/asyncLocalStorage.d.ts → modules/storage.d.ts} +0 -0
- /package/build/{services/durable/asyncLocalStorage.js → modules/storage.js} +0 -0
- /package/{services/durable/asyncLocalStorage.ts → modules/storage.ts} +0 -0
|
@@ -5,11 +5,11 @@ const errors_1 = require("../../modules/errors");
|
|
|
5
5
|
const activity_1 = require("./activity");
|
|
6
6
|
const collator_1 = require("../collator");
|
|
7
7
|
const pipe_1 = require("../pipe");
|
|
8
|
-
const
|
|
8
|
+
const task_1 = require("../task");
|
|
9
9
|
const telemetry_1 = require("../telemetry");
|
|
10
10
|
const stream_1 = require("../../types/stream");
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Supports `signal hook`, `time hook`, and `cycle hook` patterns
|
|
13
13
|
*/
|
|
14
14
|
class Hook extends activity_1.Activity {
|
|
15
15
|
constructor(config, data, metadata, hook, engine, context) {
|
|
@@ -17,45 +17,23 @@ class Hook extends activity_1.Activity {
|
|
|
17
17
|
}
|
|
18
18
|
//******** INITIAL ENTRY POINT (A) ********//
|
|
19
19
|
async process() {
|
|
20
|
-
this.logger.debug('hook-process', {
|
|
20
|
+
this.logger.debug('hook-process', {
|
|
21
|
+
jid: this.context.metadata.jid,
|
|
22
|
+
gid: this.context.metadata.gid,
|
|
23
|
+
aid: this.metadata.aid,
|
|
24
|
+
});
|
|
21
25
|
let telemetry;
|
|
22
26
|
try {
|
|
23
|
-
this.
|
|
24
|
-
await collator_1.CollatorService.notarizeEntry(this);
|
|
25
|
-
await this.getState();
|
|
26
|
-
collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
|
|
27
|
+
await this.verifyEntry();
|
|
27
28
|
telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
|
|
28
29
|
telemetry.startActivitySpan(this.leg);
|
|
29
|
-
let multiResponse;
|
|
30
|
-
const multi = this.store.getMulti();
|
|
31
30
|
if (this.doesHook()) {
|
|
32
31
|
//sleep and wait to awaken upon a signal
|
|
33
|
-
await this.
|
|
34
|
-
this.mapOutputData();
|
|
35
|
-
this.mapJobData();
|
|
36
|
-
await this.setState(multi);
|
|
37
|
-
await collator_1.CollatorService.authorizeReentry(this, multi);
|
|
38
|
-
await this.setStatus(0, multi);
|
|
39
|
-
await multi.exec();
|
|
40
|
-
telemetry.mapActivityAttributes();
|
|
32
|
+
await this.doHook(telemetry);
|
|
41
33
|
}
|
|
42
34
|
else {
|
|
43
35
|
//end the activity and transition to its children
|
|
44
|
-
|
|
45
|
-
this.mapOutputData();
|
|
46
|
-
this.mapJobData();
|
|
47
|
-
await this.setState(multi);
|
|
48
|
-
await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
|
|
49
|
-
await this.setStatus(this.adjacencyList.length - 1, multi);
|
|
50
|
-
multiResponse = await multi.exec();
|
|
51
|
-
telemetry.mapActivityAttributes();
|
|
52
|
-
const jobStatus = this.resolveStatus(multiResponse);
|
|
53
|
-
const attrs = { 'app.job.jss': jobStatus };
|
|
54
|
-
const messageIds = await this.transition(this.adjacencyList, jobStatus);
|
|
55
|
-
if (messageIds.length) {
|
|
56
|
-
attrs['app.activity.mids'] = messageIds.join(',');
|
|
57
|
-
}
|
|
58
|
-
telemetry.setActivityAttributes(attrs);
|
|
36
|
+
await this.doPassThrough(telemetry);
|
|
59
37
|
}
|
|
60
38
|
return this.context.metadata.aid;
|
|
61
39
|
}
|
|
@@ -64,6 +42,10 @@ class Hook extends activity_1.Activity {
|
|
|
64
42
|
this.logger.error('hook-inactive-job-error', { error });
|
|
65
43
|
return;
|
|
66
44
|
}
|
|
45
|
+
else if (error instanceof errors_1.GenerationalError) {
|
|
46
|
+
this.logger.info('process-event-generational-job-error', { error });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
67
49
|
else if (error instanceof errors_1.GetStateError) {
|
|
68
50
|
this.logger.error('hook-get-state-error', { error });
|
|
69
51
|
return;
|
|
@@ -76,32 +58,65 @@ class Hook extends activity_1.Activity {
|
|
|
76
58
|
}
|
|
77
59
|
finally {
|
|
78
60
|
telemetry?.endActivitySpan();
|
|
79
|
-
this.logger.debug('hook-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
|
|
61
|
+
this.logger.debug('hook-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
80
62
|
}
|
|
81
63
|
}
|
|
82
|
-
|
|
64
|
+
/**
|
|
65
|
+
* does this activity use a time-hook or web-hook
|
|
66
|
+
*/
|
|
83
67
|
doesHook() {
|
|
84
|
-
//does this activity use a time-hook or web-hook
|
|
85
68
|
return !!(this.config.hook?.topic || this.config.sleep);
|
|
86
69
|
}
|
|
70
|
+
async doHook(telemetry) {
|
|
71
|
+
const multi = this.store.getMulti();
|
|
72
|
+
await this.registerHook(multi);
|
|
73
|
+
this.mapOutputData();
|
|
74
|
+
this.mapJobData();
|
|
75
|
+
await this.setState(multi);
|
|
76
|
+
await collator_1.CollatorService.authorizeReentry(this, multi);
|
|
77
|
+
await this.setStatus(0, multi);
|
|
78
|
+
await multi.exec();
|
|
79
|
+
telemetry.mapActivityAttributes();
|
|
80
|
+
}
|
|
81
|
+
async doPassThrough(telemetry) {
|
|
82
|
+
const multi = this.store.getMulti();
|
|
83
|
+
let multiResponse;
|
|
84
|
+
this.adjacencyList = await this.filterAdjacent();
|
|
85
|
+
this.mapOutputData();
|
|
86
|
+
this.mapJobData();
|
|
87
|
+
await this.setState(multi);
|
|
88
|
+
await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
|
|
89
|
+
await this.setStatus(this.adjacencyList.length - 1, multi);
|
|
90
|
+
multiResponse = await multi.exec();
|
|
91
|
+
telemetry.mapActivityAttributes();
|
|
92
|
+
const jobStatus = this.resolveStatus(multiResponse);
|
|
93
|
+
const attrs = { 'app.job.jss': jobStatus };
|
|
94
|
+
const messageIds = await this.transition(this.adjacencyList, jobStatus);
|
|
95
|
+
if (messageIds.length) {
|
|
96
|
+
attrs['app.activity.mids'] = messageIds.join(',');
|
|
97
|
+
}
|
|
98
|
+
telemetry.setActivityAttributes(attrs);
|
|
99
|
+
}
|
|
87
100
|
async getHookRule(topic) {
|
|
88
101
|
const rules = await this.store.getHookRules();
|
|
89
102
|
return rules?.[topic]?.[0];
|
|
90
103
|
}
|
|
91
104
|
async registerHook(multi) {
|
|
92
105
|
if (this.config.hook?.topic) {
|
|
93
|
-
const
|
|
94
|
-
return await
|
|
106
|
+
const taskService = new task_1.TaskService(this.store, this.logger);
|
|
107
|
+
return await taskService.registerWebHook(this.config.hook.topic, this.context, this.resolveDad(), multi);
|
|
95
108
|
}
|
|
96
109
|
else if (this.config.sleep) {
|
|
97
110
|
const durationInSeconds = pipe_1.Pipe.resolve(this.config.sleep, this.context);
|
|
98
111
|
const jobId = this.context.metadata.jid;
|
|
112
|
+
const gId = this.context.metadata.gid;
|
|
99
113
|
const activityId = this.metadata.aid;
|
|
100
114
|
const dId = this.metadata.dad;
|
|
101
|
-
await this.engine.
|
|
115
|
+
await this.engine.taskService.registerTimeHook(jobId, gId, `${activityId}${dId || ''}`, 'sleep', durationInSeconds);
|
|
102
116
|
return jobId;
|
|
103
117
|
}
|
|
104
118
|
}
|
|
119
|
+
//******** SIGNAL RE-ENTRY POINT ********//
|
|
105
120
|
async processWebHookEvent(status = stream_1.StreamStatus.SUCCESS, code = 200) {
|
|
106
121
|
this.logger.debug('hook-process-web-hook-event', {
|
|
107
122
|
topic: this.config.hook.topic,
|
|
@@ -109,22 +124,24 @@ class Hook extends activity_1.Activity {
|
|
|
109
124
|
status,
|
|
110
125
|
code,
|
|
111
126
|
});
|
|
112
|
-
const
|
|
127
|
+
const taskService = new task_1.TaskService(this.store, this.logger);
|
|
113
128
|
const data = { ...this.data };
|
|
114
|
-
const signal = await
|
|
129
|
+
const signal = await taskService.processWebHookSignal(this.config.hook.topic, data);
|
|
115
130
|
if (signal) {
|
|
116
|
-
const [jobId,
|
|
131
|
+
const [jobId, _aid, dad, gId] = signal;
|
|
117
132
|
this.context.metadata.jid = jobId;
|
|
133
|
+
this.context.metadata.gid = gId;
|
|
118
134
|
this.context.metadata.dad = dad;
|
|
119
135
|
await this.processEvent(status, code, 'hook');
|
|
120
|
-
if (code === 200) {
|
|
121
|
-
await
|
|
122
|
-
}
|
|
136
|
+
if (code === 200) {
|
|
137
|
+
await taskService.deleteWebHookSignal(this.config.hook.topic, data);
|
|
138
|
+
} //else => 202/keep alive
|
|
123
139
|
} //else => already resolved
|
|
124
140
|
}
|
|
125
141
|
async processTimeHookEvent(jobId) {
|
|
126
142
|
this.logger.debug('hook-process-time-hook-event', {
|
|
127
143
|
jid: jobId,
|
|
144
|
+
gid: this.context.metadata.gid,
|
|
128
145
|
aid: this.metadata.aid
|
|
129
146
|
});
|
|
130
147
|
await this.processEvent(stream_1.StreamStatus.SUCCESS, 200, 'hook');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Interrupt = void 0;
|
|
4
|
-
const activity_1 = require("./activity");
|
|
5
4
|
const errors_1 = require("../../modules/errors");
|
|
5
|
+
const activity_1 = require("./activity");
|
|
6
6
|
const collator_1 = require("../collator");
|
|
7
7
|
const telemetry_1 = require("../telemetry");
|
|
8
8
|
const pipe_1 = require("../pipe");
|
|
@@ -12,20 +12,17 @@ class Interrupt extends activity_1.Activity {
|
|
|
12
12
|
}
|
|
13
13
|
//******** LEG 1 ENTRY ********//
|
|
14
14
|
async process() {
|
|
15
|
-
this.logger.debug('interrupt-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
|
|
15
|
+
this.logger.debug('interrupt-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
16
16
|
let telemetry;
|
|
17
17
|
try {
|
|
18
|
-
this.
|
|
19
|
-
await collator_1.CollatorService.notarizeEntry(this);
|
|
20
|
-
await this.getState();
|
|
21
|
-
collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid); // Ensure job active
|
|
18
|
+
await this.verifyEntry();
|
|
22
19
|
telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
|
|
23
20
|
telemetry.startActivitySpan(this.leg);
|
|
24
21
|
if (this.isInterruptingSelf()) {
|
|
25
|
-
|
|
22
|
+
await this.interruptSelf(telemetry);
|
|
26
23
|
}
|
|
27
24
|
else {
|
|
28
|
-
|
|
25
|
+
await this.interruptAnother(telemetry);
|
|
29
26
|
}
|
|
30
27
|
}
|
|
31
28
|
catch (error) {
|
|
@@ -33,6 +30,10 @@ class Interrupt extends activity_1.Activity {
|
|
|
33
30
|
this.logger.error('interrupt-inactive-job-error', { error });
|
|
34
31
|
return;
|
|
35
32
|
}
|
|
33
|
+
else if (error instanceof errors_1.GenerationalError) {
|
|
34
|
+
this.logger.info('process-event-generational-job-error', { error });
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
36
37
|
else if (error instanceof errors_1.GetStateError) {
|
|
37
38
|
this.logger.error('interrupt-get-state-error', { error });
|
|
38
39
|
return;
|
|
@@ -45,7 +46,7 @@ class Interrupt extends activity_1.Activity {
|
|
|
45
46
|
}
|
|
46
47
|
finally {
|
|
47
48
|
telemetry?.endActivitySpan();
|
|
48
|
-
this.logger.debug('interrupt-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
|
|
49
|
+
this.logger.debug('interrupt-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
async interruptSelf(telemetry) {
|
|
@@ -13,14 +13,10 @@ class Signal extends activity_1.Activity {
|
|
|
13
13
|
}
|
|
14
14
|
//******** LEG 1 ENTRY ********//
|
|
15
15
|
async process() {
|
|
16
|
-
this.logger.debug('signal-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
|
|
16
|
+
this.logger.debug('signal-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
17
17
|
let telemetry;
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
this.setLeg(1);
|
|
21
|
-
await collator_1.CollatorService.notarizeEntry(this);
|
|
22
|
-
await this.getState();
|
|
23
|
-
collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
|
|
19
|
+
await this.verifyEntry();
|
|
24
20
|
telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
|
|
25
21
|
telemetry.startActivitySpan(this.leg);
|
|
26
22
|
//save state and notarize early completion (signals only run leg1)
|
|
@@ -55,6 +51,10 @@ class Signal extends activity_1.Activity {
|
|
|
55
51
|
this.logger.error('signal-inactive-job-error', { error });
|
|
56
52
|
return;
|
|
57
53
|
}
|
|
54
|
+
else if (error instanceof errors_1.GenerationalError) {
|
|
55
|
+
this.logger.info('process-event-generational-job-error', { error });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
58
|
else if (error instanceof errors_1.GetStateError) {
|
|
59
59
|
this.logger.error('signal-get-state-error', { error });
|
|
60
60
|
return;
|
|
@@ -67,7 +67,7 @@ class Signal extends activity_1.Activity {
|
|
|
67
67
|
}
|
|
68
68
|
finally {
|
|
69
69
|
telemetry?.endActivitySpan();
|
|
70
|
-
this.logger.debug('signal-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
|
|
70
|
+
this.logger.debug('signal-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
mapSignalData() {
|
|
@@ -55,7 +55,7 @@ class Trigger extends activity_1.Activity {
|
|
|
55
55
|
finally {
|
|
56
56
|
telemetry?.endJobSpan();
|
|
57
57
|
telemetry?.endActivitySpan();
|
|
58
|
-
this.logger.debug('trigger-process-end', { subscribes: this.config.subscribes, jid: this.context.metadata.jid });
|
|
58
|
+
this.logger.debug('trigger-process-end', { subscribes: this.config.subscribes, jid: this.context.metadata.jid, gid: this.context.metadata.gid });
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
async setStatus(amount) {
|
|
@@ -89,8 +89,10 @@ class Trigger extends activity_1.Activity {
|
|
|
89
89
|
this.context = {
|
|
90
90
|
metadata: {
|
|
91
91
|
...this.metadata,
|
|
92
|
+
gid: (0, utils_1.guid)(),
|
|
92
93
|
ngn: this.context.metadata.ngn,
|
|
93
94
|
pj: this.context.metadata.pj,
|
|
95
|
+
pg: this.context.metadata.pg,
|
|
94
96
|
pd: this.context.metadata.pd,
|
|
95
97
|
pa: this.context.metadata.pa,
|
|
96
98
|
app: id,
|
|
@@ -156,7 +158,7 @@ class Trigger extends activity_1.Activity {
|
|
|
156
158
|
const depKey = this.config.stats?.parent;
|
|
157
159
|
const resolvedDepKey = depKey ? pipe_1.Pipe.resolve(depKey, this.context) : '';
|
|
158
160
|
if (resolvedDepKey) {
|
|
159
|
-
await this.store.setDependency(resolvedDepKey, this.context.metadata.tpc, this.context.metadata.jid, multi);
|
|
161
|
+
await this.store.setDependency(resolvedDepKey, this.context.metadata.tpc, this.context.metadata.jid, this.context.metadata.gid, multi);
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
async setStats(multi) {
|
|
@@ -13,14 +13,10 @@ class Worker extends activity_1.Activity {
|
|
|
13
13
|
}
|
|
14
14
|
//******** INITIAL ENTRY POINT (A) ********//
|
|
15
15
|
async process() {
|
|
16
|
-
this.logger.debug('worker-process', { jid: this.context.metadata.jid, aid: this.metadata.aid });
|
|
16
|
+
this.logger.debug('worker-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
17
17
|
let telemetry;
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
this.setLeg(1);
|
|
21
|
-
await collator_1.CollatorService.notarizeEntry(this);
|
|
22
|
-
await this.getState();
|
|
23
|
-
collator_1.CollatorService.assertJobActive(this.context.metadata.js, this.context.metadata.jid, this.metadata.aid);
|
|
19
|
+
await this.verifyEntry();
|
|
24
20
|
telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
|
|
25
21
|
telemetry.startActivitySpan(this.leg);
|
|
26
22
|
this.mapInputData();
|
|
@@ -46,6 +42,10 @@ class Worker extends activity_1.Activity {
|
|
|
46
42
|
this.logger.error('await-inactive-job-error', { error });
|
|
47
43
|
return;
|
|
48
44
|
}
|
|
45
|
+
else if (error instanceof errors_1.GenerationalError) {
|
|
46
|
+
this.logger.info('process-event-generational-job-error', { error });
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
49
|
else if (error instanceof errors_1.GetStateError) {
|
|
50
50
|
this.logger.error('worker-get-state-error', { error });
|
|
51
51
|
return;
|
|
@@ -58,7 +58,7 @@ class Worker extends activity_1.Activity {
|
|
|
58
58
|
}
|
|
59
59
|
finally {
|
|
60
60
|
telemetry?.endActivitySpan();
|
|
61
|
-
this.logger.debug('worker-process-end', { jid: this.context.metadata.jid, aid: this.metadata.aid });
|
|
61
|
+
this.logger.debug('worker-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
async execActivity(multi) {
|
|
@@ -67,6 +67,7 @@ class Worker extends activity_1.Activity {
|
|
|
67
67
|
metadata: {
|
|
68
68
|
guid: (0, utils_1.guid)(),
|
|
69
69
|
jid: this.context.metadata.jid,
|
|
70
|
+
gid: this.context.metadata.gid,
|
|
70
71
|
dad: this.metadata.dad,
|
|
71
72
|
aid: this.metadata.aid,
|
|
72
73
|
topic,
|
|
@@ -80,7 +81,7 @@ class Worker extends activity_1.Activity {
|
|
|
80
81
|
retry: this.config.retry
|
|
81
82
|
};
|
|
82
83
|
}
|
|
83
|
-
return (await this.engine.
|
|
84
|
+
return (await this.engine.router?.publishMessage(topic, streamData, multi));
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
exports.Worker = Worker;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MeshOSService = void 0;
|
|
4
4
|
const _1 = require(".");
|
|
5
|
-
const
|
|
5
|
+
const storage_1 = require("../../modules/storage");
|
|
6
6
|
const client_1 = require("./client");
|
|
7
7
|
const search_1 = require("./search");
|
|
8
8
|
const worker_1 = require("./worker");
|
|
@@ -92,7 +92,7 @@ class MeshOSService {
|
|
|
92
92
|
//wrap the function to return
|
|
93
93
|
const wrappedFunction = {
|
|
94
94
|
[funcName]: async (...args) => {
|
|
95
|
-
const store =
|
|
95
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
96
96
|
const workflowId = store.get('workflowId');
|
|
97
97
|
//use a Proxy to wrap hook methods
|
|
98
98
|
const context = new Proxy(my, {
|
|
@@ -3,7 +3,7 @@ var _a;
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.WorkerService = void 0;
|
|
5
5
|
const errors_1 = require("../../modules/errors");
|
|
6
|
-
const
|
|
6
|
+
const storage_1 = require("../../modules/storage");
|
|
7
7
|
const factory_1 = require("./factory");
|
|
8
8
|
const hotmesh_1 = require("../hotmesh");
|
|
9
9
|
const search_1 = require("./search");
|
|
@@ -173,7 +173,7 @@ class WorkerService {
|
|
|
173
173
|
context.set('workflowName', workflowTopic.split('-').pop());
|
|
174
174
|
context.set('workflowTrace', data.metadata.trc);
|
|
175
175
|
context.set('workflowSpan', data.metadata.spn);
|
|
176
|
-
const workflowResponse = await
|
|
176
|
+
const workflowResponse = await storage_1.asyncLocalStorage.run(context, async () => {
|
|
177
177
|
return await workflowFunction.apply(this, workflowInput.arguments);
|
|
178
178
|
});
|
|
179
179
|
return {
|
|
@@ -7,7 +7,7 @@ exports.WorkflowService = void 0;
|
|
|
7
7
|
const ms_1 = __importDefault(require("ms"));
|
|
8
8
|
const errors_1 = require("../../modules/errors");
|
|
9
9
|
const key_1 = require("../../modules/key");
|
|
10
|
-
const
|
|
10
|
+
const storage_1 = require("../../modules/storage");
|
|
11
11
|
const client_1 = require("./client");
|
|
12
12
|
const connection_1 = require("./connection");
|
|
13
13
|
const factory_1 = require("./factory");
|
|
@@ -23,7 +23,7 @@ class WorkflowService {
|
|
|
23
23
|
* @returns {Promise<T>} - the result of the child workflow
|
|
24
24
|
*/
|
|
25
25
|
static async executeChild(options) {
|
|
26
|
-
const store =
|
|
26
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
27
27
|
const namespace = store.get('namespace');
|
|
28
28
|
const workflowId = store.get('workflowId');
|
|
29
29
|
const originJobId = store.get('originJobId');
|
|
@@ -67,7 +67,7 @@ class WorkflowService {
|
|
|
67
67
|
* @returns {Promise<string>} - the childJobId
|
|
68
68
|
*/
|
|
69
69
|
static async startChild(options) {
|
|
70
|
-
const store =
|
|
70
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
71
71
|
const namespace = store.get('namespace');
|
|
72
72
|
const workflowId = store.get('workflowId');
|
|
73
73
|
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
@@ -140,7 +140,7 @@ class WorkflowService {
|
|
|
140
140
|
* @returns {Promise<Search>} - a search session
|
|
141
141
|
*/
|
|
142
142
|
static async search() {
|
|
143
|
-
const store =
|
|
143
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
144
144
|
const workflowId = store.get('workflowId');
|
|
145
145
|
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
146
146
|
const workflowTopic = store.get('workflowTopic');
|
|
@@ -157,7 +157,7 @@ class WorkflowService {
|
|
|
157
157
|
* @returns {Promise<HotMesh>} - a hotmesh client
|
|
158
158
|
*/
|
|
159
159
|
static async getHotMesh() {
|
|
160
|
-
const store =
|
|
160
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
161
161
|
const workflowTopic = store.get('workflowTopic');
|
|
162
162
|
const namespace = store.get('namespace');
|
|
163
163
|
return await worker_1.WorkerService.getHotMesh(workflowTopic, { namespace });
|
|
@@ -167,7 +167,7 @@ class WorkflowService {
|
|
|
167
167
|
* @returns {WorkflowContext} - the current workflow context
|
|
168
168
|
*/
|
|
169
169
|
static getContext() {
|
|
170
|
-
const store =
|
|
170
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
171
171
|
const workflowId = store.get('workflowId');
|
|
172
172
|
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
173
173
|
const workflowTopic = store.get('workflowTopic');
|
|
@@ -192,7 +192,7 @@ class WorkflowService {
|
|
|
192
192
|
* @private
|
|
193
193
|
*/
|
|
194
194
|
static async isSideEffectAllowed(hotMeshClient, prefix) {
|
|
195
|
-
const store =
|
|
195
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
196
196
|
const workflowId = store.get('workflowId');
|
|
197
197
|
const workflowDimension = store.get('workflowDimension') ?? '';
|
|
198
198
|
const COUNTER = store.get('counter');
|
|
@@ -213,7 +213,7 @@ class WorkflowService {
|
|
|
213
213
|
* @returns {number} - a random number between 0 and 1
|
|
214
214
|
*/
|
|
215
215
|
static random() {
|
|
216
|
-
const store =
|
|
216
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
217
217
|
const COUNTER = store.get('counter');
|
|
218
218
|
const seed = COUNTER.counter = COUNTER.counter + 1;
|
|
219
219
|
return (0, utils_1.deterministicRandom)(seed);
|
|
@@ -226,7 +226,7 @@ class WorkflowService {
|
|
|
226
226
|
* @returns {Promise<string>} - the stream id
|
|
227
227
|
*/
|
|
228
228
|
static async signal(signalId, data) {
|
|
229
|
-
const store =
|
|
229
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
230
230
|
const workflowTopic = store.get('workflowTopic');
|
|
231
231
|
const namespace = store.get('namespace');
|
|
232
232
|
const hotMeshClient = await worker_1.WorkerService.getHotMesh(workflowTopic, { namespace });
|
|
@@ -243,12 +243,12 @@ class WorkflowService {
|
|
|
243
243
|
* @param {HookOptions} options - the hook options
|
|
244
244
|
*/
|
|
245
245
|
static async hook(options) {
|
|
246
|
-
const store =
|
|
246
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
247
247
|
const workflowTopic = store.get('workflowTopic');
|
|
248
248
|
const namespace = store.get('namespace');
|
|
249
249
|
const hotMeshClient = await worker_1.WorkerService.getHotMesh(workflowTopic, { namespace });
|
|
250
250
|
if (await WorkflowService.isSideEffectAllowed(hotMeshClient, 'hook')) {
|
|
251
|
-
const store =
|
|
251
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
252
252
|
const workflowId = options.workflowId ?? store.get('workflowId');
|
|
253
253
|
let workflowTopic = store.get('workflowTopic');
|
|
254
254
|
if (options.entity || (options.taskQueue && options.workflowName)) {
|
|
@@ -264,7 +264,7 @@ class WorkflowService {
|
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
266
|
static getLocalState() {
|
|
267
|
-
const store =
|
|
267
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
268
268
|
return {
|
|
269
269
|
workflowId: store.get('workflowId'),
|
|
270
270
|
namespace: store.get('namespace'),
|
|
@@ -306,7 +306,7 @@ class WorkflowService {
|
|
|
306
306
|
* @returns {Promise<string>} - the stream id
|
|
307
307
|
*/
|
|
308
308
|
static async interrupt(jobId, options = {}) {
|
|
309
|
-
const store =
|
|
309
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
310
310
|
const workflowTopic = store.get('workflowTopic');
|
|
311
311
|
const namespace = store.get('namespace');
|
|
312
312
|
const hotMeshClient = await worker_1.WorkerService.getHotMesh(workflowTopic, { namespace });
|
|
@@ -323,7 +323,7 @@ class WorkflowService {
|
|
|
323
323
|
*/
|
|
324
324
|
static async sleepFor(duration) {
|
|
325
325
|
const seconds = (0, ms_1.default)(duration) / 1000;
|
|
326
|
-
const store =
|
|
326
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
327
327
|
const namespace = store.get('namespace');
|
|
328
328
|
const workflowTopic = store.get('workflowTopic');
|
|
329
329
|
const hotMeshClient = await worker_1.WorkerService.getHotMesh(workflowTopic, { namespace });
|
|
@@ -348,7 +348,7 @@ class WorkflowService {
|
|
|
348
348
|
*/
|
|
349
349
|
static async sleep(duration) {
|
|
350
350
|
const seconds = (0, ms_1.default)(duration) / 1000;
|
|
351
|
-
const store =
|
|
351
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
352
352
|
const COUNTER = store.get('counter');
|
|
353
353
|
const execIndex = COUNTER.counter = COUNTER.counter + 1;
|
|
354
354
|
const workflowId = store.get('workflowId');
|
|
@@ -374,7 +374,7 @@ class WorkflowService {
|
|
|
374
374
|
* @returns {Promise<Record<any, any>[]>}
|
|
375
375
|
*/
|
|
376
376
|
static async waitForSignal(signals, options) {
|
|
377
|
-
const store =
|
|
377
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
378
378
|
const COUNTER = store.get('counter');
|
|
379
379
|
const workflowId = store.get('workflowId');
|
|
380
380
|
const workflowTopic = store.get('workflowTopic');
|
|
@@ -427,7 +427,7 @@ class WorkflowService {
|
|
|
427
427
|
}
|
|
428
428
|
static wrapActivity(activityName, options) {
|
|
429
429
|
return async function () {
|
|
430
|
-
const store =
|
|
430
|
+
const store = storage_1.asyncLocalStorage.getStore();
|
|
431
431
|
const COUNTER = store.get('counter');
|
|
432
432
|
//increment by state (not value) to avoid race conditions
|
|
433
433
|
const execIndex = COUNTER.counter = COUNTER.counter + 1;
|
|
@@ -6,8 +6,7 @@ import { Signal } from '../activities/signal';
|
|
|
6
6
|
import { Worker } from '../activities/worker';
|
|
7
7
|
import { Trigger } from '../activities/trigger';
|
|
8
8
|
import { ILogger } from '../logger';
|
|
9
|
-
import {
|
|
10
|
-
import { StreamSignaler } from '../signaler/stream';
|
|
9
|
+
import { Router } from '../router';
|
|
11
10
|
import { StoreService } from '../store';
|
|
12
11
|
import { StreamService } from '../stream';
|
|
13
12
|
import { SubService } from '../sub';
|
|
@@ -27,12 +26,11 @@ declare class EngineService {
|
|
|
27
26
|
apps: HotMeshApps | null;
|
|
28
27
|
appId: string;
|
|
29
28
|
guid: string;
|
|
29
|
+
router: Router | null;
|
|
30
30
|
store: StoreService<RedisClient, RedisMulti> | null;
|
|
31
31
|
stream: StreamService<RedisClient, RedisMulti> | null;
|
|
32
32
|
subscribe: SubService<RedisClient, RedisMulti> | null;
|
|
33
|
-
|
|
34
|
-
streamSignaler: StreamSignaler | null;
|
|
35
|
-
task: TaskService | null;
|
|
33
|
+
taskService: TaskService | null;
|
|
36
34
|
logger: ILogger;
|
|
37
35
|
cacheMode: CacheMode;
|
|
38
36
|
untilVersion: string | null;
|
|
@@ -44,7 +42,7 @@ declare class EngineService {
|
|
|
44
42
|
initStoreChannel(store: RedisClient): Promise<void>;
|
|
45
43
|
initSubChannel(sub: RedisClient): Promise<void>;
|
|
46
44
|
initStreamChannel(stream: RedisClient): Promise<void>;
|
|
47
|
-
|
|
45
|
+
initRouter(config: HotMeshConfig): Router;
|
|
48
46
|
getVID(vid?: AppVID): Promise<AppVID>;
|
|
49
47
|
setCacheMode(cacheMode: CacheMode, untilVersion: string): void;
|
|
50
48
|
routeToSubscribers(topic: string, message: JobOutput): Promise<void>;
|
|
@@ -67,7 +65,7 @@ declare class EngineService {
|
|
|
67
65
|
interrupt(topic: string, jobId: string, options?: JobInterruptOptions): Promise<string>;
|
|
68
66
|
scrub(jobId: string): Promise<void>;
|
|
69
67
|
hook(topic: string, data: JobData, status?: StreamStatus, code?: StreamCode): Promise<string>;
|
|
70
|
-
hookTime(jobId: string, activityId: string, type?: 'sleep' | 'expire' | 'interrupt'): Promise<string | void>;
|
|
68
|
+
hookTime(jobId: string, gId: string, activityId: string, type?: 'sleep' | 'expire' | 'interrupt'): Promise<string | void>;
|
|
71
69
|
hookAll(hookTopic: string, data: JobData, keyResolver: JobStatsInput, queryFacets?: string[]): Promise<string[]>;
|
|
72
70
|
pub(topic: string, data: JobData, context?: JobState): Promise<string>;
|
|
73
71
|
sub(topic: string, callback: JobMessageCallback): Promise<void>;
|