@hotmeshio/hotmesh 0.0.55 → 0.0.57
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 +1 -1
- package/build/modules/enums.js +1 -10
- package/build/modules/key.d.ts +0 -38
- package/build/modules/key.js +4 -46
- package/build/modules/utils.d.ts +0 -8
- package/build/modules/utils.js +0 -14
- package/build/package.json +11 -4
- package/build/services/activities/activity.d.ts +0 -28
- package/build/services/activities/activity.js +1 -46
- package/build/services/activities/await.js +0 -4
- package/build/services/activities/cycle.d.ts +0 -7
- package/build/services/activities/cycle.js +1 -16
- package/build/services/activities/hook.d.ts +0 -6
- package/build/services/activities/hook.js +2 -12
- package/build/services/activities/interrupt.js +0 -8
- package/build/services/activities/signal.d.ts +0 -6
- package/build/services/activities/signal.js +0 -15
- package/build/services/activities/trigger.d.ts +0 -4
- package/build/services/activities/trigger.js +1 -7
- package/build/services/activities/worker.js +0 -4
- package/build/services/collator/index.d.ts +0 -70
- package/build/services/collator/index.js +1 -91
- package/build/services/compiler/deployer.js +6 -38
- package/build/services/compiler/index.d.ts +0 -15
- package/build/services/compiler/index.js +0 -20
- package/build/services/compiler/validator.d.ts +0 -3
- package/build/services/compiler/validator.js +0 -25
- package/build/services/connector/clients/ioredis.d.ts +2 -2
- package/build/services/connector/clients/ioredis.js +0 -2
- package/build/services/connector/clients/redis.d.ts +4 -4
- package/build/services/connector/clients/redis.js +1 -3
- package/build/services/connector/index.d.ts +1 -1
- package/build/services/connector/index.js +0 -2
- package/build/services/durable/client.d.ts +1 -26
- package/build/services/durable/client.js +0 -56
- package/build/services/durable/exporter.d.ts +0 -22
- package/build/services/durable/exporter.js +1 -30
- package/build/services/durable/handle.d.ts +0 -36
- package/build/services/durable/handle.js +0 -46
- package/build/services/durable/index.d.ts +0 -4
- package/build/services/durable/index.js +0 -4
- package/build/services/durable/schemas/factory.d.ts +0 -29
- package/build/services/durable/schemas/factory.js +0 -29
- package/build/services/durable/search.d.ts +1 -36
- package/build/services/durable/search.js +56 -56
- package/build/services/durable/worker.js +2 -22
- package/build/services/durable/workflow.d.ts +0 -114
- package/build/services/durable/workflow.js +1 -141
- package/build/services/engine/index.d.ts +1 -6
- package/build/services/engine/index.js +1 -43
- package/build/services/exporter/index.d.ts +0 -27
- package/build/services/exporter/index.js +0 -33
- package/build/services/hotmesh/index.d.ts +2 -2
- package/build/services/hotmesh/index.js +1 -9
- package/build/services/logger/index.js +0 -2
- package/build/services/mapper/index.d.ts +0 -14
- package/build/services/mapper/index.js +0 -14
- package/build/services/pipe/functions/date.d.ts +0 -7
- package/build/services/pipe/functions/date.js +0 -7
- package/build/services/pipe/functions/math.js +0 -2
- package/build/services/pipe/index.d.ts +0 -15
- package/build/services/pipe/index.js +2 -23
- package/build/services/quorum/index.d.ts +0 -7
- package/build/services/quorum/index.js +0 -21
- package/build/services/reporter/index.d.ts +0 -5
- package/build/services/reporter/index.js +0 -9
- package/build/services/router/index.d.ts +0 -9
- package/build/services/router/index.js +2 -38
- package/build/services/serializer/index.js +7 -26
- package/build/services/store/cache.d.ts +0 -18
- package/build/services/store/cache.js +0 -18
- package/build/services/store/clients/ioredis.d.ts +1 -1
- package/build/services/store/clients/ioredis.js +0 -1
- package/build/services/store/clients/redis.d.ts +1 -1
- package/build/services/store/index.d.ts +0 -55
- package/build/services/store/index.js +5 -81
- package/build/services/stream/clients/ioredis.d.ts +1 -1
- package/build/services/stream/clients/ioredis.js +1 -4
- package/build/services/stream/clients/redis.d.ts +1 -1
- package/build/services/sub/clients/ioredis.d.ts +1 -1
- package/build/services/sub/clients/redis.d.ts +1 -1
- package/build/services/task/index.d.ts +0 -9
- package/build/services/task/index.js +0 -31
- package/build/services/telemetry/index.d.ts +0 -7
- package/build/services/telemetry/index.js +1 -13
- package/build/services/worker/index.d.ts +0 -4
- package/build/services/worker/index.js +2 -6
- package/build/types/activity.d.ts +0 -81
- package/build/types/durable.d.ts +26 -177
- package/build/types/exporter.d.ts +0 -13
- package/build/types/hotmesh.d.ts +4 -16
- package/build/types/hotmesh.js +0 -3
- package/build/types/index.d.ts +4 -6
- package/build/types/index.js +4 -3
- package/build/types/job.d.ts +1 -86
- package/build/types/pipe.d.ts +0 -65
- package/build/types/quorum.d.ts +15 -10
- package/build/types/redis.d.ts +225 -7
- package/build/types/redis.js +9 -0
- package/build/types/stream.d.ts +0 -58
- package/build/types/stream.js +0 -4
- package/package.json +11 -4
- package/types/durable.ts +131 -4
- package/types/hotmesh.ts +3 -6
- package/types/index.ts +23 -10
- package/types/job.ts +1 -1
- package/types/quorum.ts +22 -0
- package/types/redis.ts +267 -18
- package/build/types/ioredisclient.d.ts +0 -5
- package/build/types/ioredisclient.js +0 -5
- package/build/types/redisclient.d.ts +0 -26
- package/build/types/redisclient.js +0 -2
- package/modules/enums.ts +0 -62
- package/modules/errors.ts +0 -280
- package/modules/key.ts +0 -101
- package/modules/storage.ts +0 -3
- package/modules/utils.ts +0 -242
- package/services/activities/activity.ts +0 -589
- package/services/activities/await.ts +0 -113
- package/services/activities/cycle.ts +0 -115
- package/services/activities/hook.ts +0 -197
- package/services/activities/index.ts +0 -19
- package/services/activities/interrupt.ts +0 -172
- package/services/activities/signal.ts +0 -148
- package/services/activities/trigger.ts +0 -295
- package/services/activities/worker.ts +0 -107
- package/services/collator/README.md +0 -102
- package/services/collator/index.ts +0 -291
- package/services/compiler/deployer.ts +0 -504
- package/services/compiler/index.ts +0 -98
- package/services/compiler/validator.ts +0 -158
- package/services/connector/clients/ioredis.ts +0 -57
- package/services/connector/clients/redis.ts +0 -72
- package/services/connector/index.ts +0 -42
- package/services/durable/client.ts +0 -266
- package/services/durable/connection.ts +0 -10
- package/services/durable/exporter.ts +0 -232
- package/services/durable/handle.ts +0 -160
- package/services/durable/index.ts +0 -27
- package/services/durable/schemas/factory.ts +0 -2358
- package/services/durable/search.ts +0 -196
- package/services/durable/worker.ts +0 -401
- package/services/durable/workflow.ts +0 -557
- package/services/engine/index.ts +0 -761
- package/services/exporter/index.ts +0 -146
- package/services/hotmesh/index.ts +0 -237
- package/services/logger/index.ts +0 -79
- package/services/mapper/index.ts +0 -89
- package/services/pipe/functions/array.ts +0 -78
- package/services/pipe/functions/bitwise.ts +0 -27
- package/services/pipe/functions/conditional.ts +0 -35
- package/services/pipe/functions/date.ts +0 -220
- package/services/pipe/functions/index.ts +0 -27
- package/services/pipe/functions/json.ts +0 -11
- package/services/pipe/functions/logical.ts +0 -11
- package/services/pipe/functions/math.ts +0 -217
- package/services/pipe/functions/number.ts +0 -75
- package/services/pipe/functions/object.ts +0 -98
- package/services/pipe/functions/string.ts +0 -86
- package/services/pipe/functions/symbol.ts +0 -39
- package/services/pipe/functions/unary.ts +0 -19
- package/services/pipe/index.ts +0 -216
- package/services/quorum/index.ts +0 -319
- package/services/reporter/index.ts +0 -387
- package/services/router/index.ts +0 -426
- package/services/serializer/README.md +0 -10
- package/services/serializer/index.ts +0 -285
- package/services/store/cache.ts +0 -172
- package/services/store/clients/ioredis.ts +0 -145
- package/services/store/clients/redis.ts +0 -191
- package/services/store/index.ts +0 -1091
- package/services/stream/clients/ioredis.ts +0 -157
- package/services/stream/clients/redis.ts +0 -158
- package/services/stream/index.ts +0 -58
- package/services/sub/clients/ioredis.ts +0 -83
- package/services/sub/clients/redis.ts +0 -74
- package/services/sub/index.ts +0 -25
- package/services/task/index.ts +0 -250
- package/services/telemetry/index.ts +0 -273
- package/services/worker/index.ts +0 -248
- package/types/ioredisclient.ts +0 -10
- package/types/redisclient.ts +0 -30
|
@@ -8,14 +8,10 @@ const pipe_1 = require("../pipe");
|
|
|
8
8
|
const task_1 = require("../task");
|
|
9
9
|
const telemetry_1 = require("../telemetry");
|
|
10
10
|
const stream_1 = require("../../types/stream");
|
|
11
|
-
/**
|
|
12
|
-
* Supports `signal hook`, `time hook`, and `cycle hook` patterns
|
|
13
|
-
*/
|
|
14
11
|
class Hook extends activity_1.Activity {
|
|
15
12
|
constructor(config, data, metadata, hook, engine, context) {
|
|
16
13
|
super(config, data, metadata, hook, engine, context);
|
|
17
14
|
}
|
|
18
|
-
//******** INITIAL ENTRY POINT (A) ********//
|
|
19
15
|
async process() {
|
|
20
16
|
this.logger.debug('hook-process', {
|
|
21
17
|
jid: this.context.metadata.jid,
|
|
@@ -28,11 +24,9 @@ class Hook extends activity_1.Activity {
|
|
|
28
24
|
telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
|
|
29
25
|
telemetry.startActivitySpan(this.leg);
|
|
30
26
|
if (this.doesHook()) {
|
|
31
|
-
//sleep and wait to awaken upon a signal
|
|
32
27
|
await this.doHook(telemetry);
|
|
33
28
|
}
|
|
34
29
|
else {
|
|
35
|
-
//end the activity and transition to its children
|
|
36
30
|
await this.doPassThrough(telemetry);
|
|
37
31
|
}
|
|
38
32
|
return this.context.metadata.aid;
|
|
@@ -61,9 +55,6 @@ class Hook extends activity_1.Activity {
|
|
|
61
55
|
this.logger.debug('hook-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
62
56
|
}
|
|
63
57
|
}
|
|
64
|
-
/**
|
|
65
|
-
* does this activity use a time-hook or web-hook
|
|
66
|
-
*/
|
|
67
58
|
doesHook() {
|
|
68
59
|
if (this.config.sleep) {
|
|
69
60
|
const duration = pipe_1.Pipe.resolve(this.config.sleep, this.context);
|
|
@@ -115,7 +106,6 @@ class Hook extends activity_1.Activity {
|
|
|
115
106
|
return this.context.metadata.jid;
|
|
116
107
|
}
|
|
117
108
|
}
|
|
118
|
-
//******** SIGNAL RE-ENTRY POINT ********//
|
|
119
109
|
async processWebHookEvent(status = stream_1.StreamStatus.SUCCESS, code = 200) {
|
|
120
110
|
this.logger.debug('hook-process-web-hook-event', {
|
|
121
111
|
topic: this.config.hook.topic,
|
|
@@ -134,8 +124,8 @@ class Hook extends activity_1.Activity {
|
|
|
134
124
|
await this.processEvent(status, code, 'hook');
|
|
135
125
|
if (code === 200) {
|
|
136
126
|
await taskService.deleteWebHookSignal(this.config.hook.topic, data);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
139
129
|
}
|
|
140
130
|
async processTimeHookEvent(jobId) {
|
|
141
131
|
this.logger.debug('hook-process-time-hook-event', {
|
|
@@ -10,7 +10,6 @@ class Interrupt extends activity_1.Activity {
|
|
|
10
10
|
constructor(config, data, metadata, hook, engine, context) {
|
|
11
11
|
super(config, data, metadata, hook, engine, context);
|
|
12
12
|
}
|
|
13
|
-
//******** LEG 1 ENTRY ********//
|
|
14
13
|
async process() {
|
|
15
14
|
this.logger.debug('interrupt-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
16
15
|
let telemetry;
|
|
@@ -50,14 +49,11 @@ class Interrupt extends activity_1.Activity {
|
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
async interruptSelf(telemetry) {
|
|
53
|
-
// Apply final updates to THIS job's state
|
|
54
52
|
if (this.config.job?.maps) {
|
|
55
53
|
this.mapJobData();
|
|
56
54
|
await this.setState();
|
|
57
55
|
}
|
|
58
|
-
// Interrupt THIS job
|
|
59
56
|
const messageId = await this.interrupt();
|
|
60
|
-
// Notarize completion and log
|
|
61
57
|
telemetry.mapActivityAttributes();
|
|
62
58
|
const multi = this.store.getMulti();
|
|
63
59
|
await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
|
|
@@ -71,10 +67,8 @@ class Interrupt extends activity_1.Activity {
|
|
|
71
67
|
return this.context.metadata.aid;
|
|
72
68
|
}
|
|
73
69
|
async interruptAnother(telemetry) {
|
|
74
|
-
// Interrupt ANOTHER job
|
|
75
70
|
const messageId = await this.interrupt();
|
|
76
71
|
const attrs = { 'app.activity.mid': messageId };
|
|
77
|
-
// Apply updates to THIS job's state
|
|
78
72
|
telemetry.mapActivityAttributes();
|
|
79
73
|
this.adjacencyList = await this.filterAdjacent();
|
|
80
74
|
if (this.config.job?.maps || this.config.output?.maps) {
|
|
@@ -83,14 +77,12 @@ class Interrupt extends activity_1.Activity {
|
|
|
83
77
|
const multi = this.store.getMulti();
|
|
84
78
|
await this.setState(multi);
|
|
85
79
|
}
|
|
86
|
-
// Notarize completion
|
|
87
80
|
const multi = this.store.getMulti();
|
|
88
81
|
await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
|
|
89
82
|
await this.setStatus(this.adjacencyList.length - 1, multi);
|
|
90
83
|
const multiResponse = await multi.exec();
|
|
91
84
|
const jobStatus = this.resolveStatus(multiResponse);
|
|
92
85
|
attrs['app.job.jss'] = jobStatus;
|
|
93
|
-
// Transition next generation and log
|
|
94
86
|
const messageIds = await this.transition(this.adjacencyList, jobStatus);
|
|
95
87
|
if (messageIds.length) {
|
|
96
88
|
attrs['app.activity.mids'] = messageIds.join(',');
|
|
@@ -8,13 +8,7 @@ declare class Signal extends Activity {
|
|
|
8
8
|
process(): Promise<string>;
|
|
9
9
|
mapSignalData(): Record<string, any>;
|
|
10
10
|
mapResolverData(): Record<string, any>;
|
|
11
|
-
/**
|
|
12
|
-
* The signal activity will hook one
|
|
13
|
-
*/
|
|
14
11
|
hookOne(): Promise<string>;
|
|
15
|
-
/**
|
|
16
|
-
* The signal activity will hook all paused jobs that share the same job key.
|
|
17
|
-
*/
|
|
18
12
|
hookAll(): Promise<string[]>;
|
|
19
13
|
}
|
|
20
14
|
export { Signal };
|
|
@@ -11,7 +11,6 @@ class Signal extends activity_1.Activity {
|
|
|
11
11
|
constructor(config, data, metadata, hook, engine, context) {
|
|
12
12
|
super(config, data, metadata, hook, engine, context);
|
|
13
13
|
}
|
|
14
|
-
//******** LEG 1 ENTRY ********//
|
|
15
14
|
async process() {
|
|
16
15
|
this.logger.debug('signal-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
17
16
|
let telemetry;
|
|
@@ -19,7 +18,6 @@ class Signal extends activity_1.Activity {
|
|
|
19
18
|
await this.verifyEntry();
|
|
20
19
|
telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
|
|
21
20
|
telemetry.startActivitySpan(this.leg);
|
|
22
|
-
//save state and notarize early completion (signals only run leg1)
|
|
23
21
|
const multi = this.store.getMulti();
|
|
24
22
|
this.adjacencyList = await this.filterAdjacent();
|
|
25
23
|
this.mapOutputData();
|
|
@@ -28,14 +26,12 @@ class Signal extends activity_1.Activity {
|
|
|
28
26
|
await collator_1.CollatorService.notarizeEarlyCompletion(this, multi);
|
|
29
27
|
await this.setStatus(this.adjacencyList.length - 1, multi);
|
|
30
28
|
const multiResponse = await multi.exec();
|
|
31
|
-
//todo: this should execute BEFORE the status is decremented
|
|
32
29
|
if (this.config.subtype === 'all') {
|
|
33
30
|
await this.hookAll();
|
|
34
31
|
}
|
|
35
32
|
else {
|
|
36
33
|
await this.hookOne();
|
|
37
34
|
}
|
|
38
|
-
//transition to adjacent activities
|
|
39
35
|
const jobStatus = this.resolveStatus(multiResponse);
|
|
40
36
|
const attrs = { 'app.job.jss': jobStatus };
|
|
41
37
|
const messageIds = await this.transition(this.adjacencyList, jobStatus);
|
|
@@ -82,9 +78,6 @@ class Signal extends activity_1.Activity {
|
|
|
82
78
|
return mapper.mapRules();
|
|
83
79
|
}
|
|
84
80
|
}
|
|
85
|
-
/**
|
|
86
|
-
* The signal activity will hook one
|
|
87
|
-
*/
|
|
88
81
|
async hookOne() {
|
|
89
82
|
const topic = pipe_1.Pipe.resolve(this.config.topic, this.context);
|
|
90
83
|
const signalInputData = this.mapSignalData();
|
|
@@ -92,23 +85,15 @@ class Signal extends activity_1.Activity {
|
|
|
92
85
|
const code = pipe_1.Pipe.resolve(this.config.code, this.context);
|
|
93
86
|
return await this.engine.hook(topic, signalInputData, status, code);
|
|
94
87
|
}
|
|
95
|
-
/**
|
|
96
|
-
* The signal activity will hook all paused jobs that share the same job key.
|
|
97
|
-
*/
|
|
98
88
|
async hookAll() {
|
|
99
|
-
//prep 1) generate `input signal data` (essentially the webhook payload)
|
|
100
89
|
const signalInputData = this.mapSignalData();
|
|
101
|
-
//prep 2) generate data that resolves the job key (per the YAML config)
|
|
102
90
|
const keyResolverData = this.mapResolverData();
|
|
103
91
|
if (this.config.scrub) {
|
|
104
|
-
//self-clean the indexes upon use if configured
|
|
105
92
|
keyResolverData.scrub = true;
|
|
106
93
|
}
|
|
107
|
-
//prep 3) jobKeys can contain multiple indexes (per the YAML config)
|
|
108
94
|
const key_name = pipe_1.Pipe.resolve(this.config.key_name, this.context);
|
|
109
95
|
const key_value = pipe_1.Pipe.resolve(this.config.key_value, this.context);
|
|
110
96
|
const indexQueryFacets = [`${key_name}:${key_value}`];
|
|
111
|
-
//execute: `hookAll` will now resume all paused jobs that share the same job key
|
|
112
97
|
return await this.engine.hookAll(this.config.topic, signalInputData, keyResolverData, indexQueryFacets);
|
|
113
98
|
}
|
|
114
99
|
}
|
|
@@ -21,10 +21,6 @@ declare class Trigger extends Activity {
|
|
|
21
21
|
resolveJobId(context: Partial<JobState>): string;
|
|
22
22
|
resolveJobKey(context: Partial<JobState>): string;
|
|
23
23
|
setStateNX(): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Registers this job as a dependent of the parent job; when the
|
|
26
|
-
* parent job is interrupted, this job will be interrupted
|
|
27
|
-
*/
|
|
28
24
|
registerJobDependency(multi?: RedisMulti): Promise<void>;
|
|
29
25
|
setStats(multi?: RedisMulti): Promise<void>;
|
|
30
26
|
}
|
|
@@ -33,8 +33,6 @@ class Trigger extends activity_1.Activity {
|
|
|
33
33
|
await this.setStats(multi);
|
|
34
34
|
await this.registerJobDependency(multi);
|
|
35
35
|
await multi.exec();
|
|
36
|
-
//if the parent (spawner) chose not to await,
|
|
37
|
-
// emit the job_id as the data payload { job_id }
|
|
38
36
|
this.execAdjacentParent();
|
|
39
37
|
telemetry.mapActivityAttributes();
|
|
40
38
|
const jobStatus = Number(this.context.metadata.js);
|
|
@@ -162,7 +160,7 @@ class Trigger extends activity_1.Activity {
|
|
|
162
160
|
},
|
|
163
161
|
};
|
|
164
162
|
this.context['$self'] = this.context[this.metadata.aid];
|
|
165
|
-
this.context['$job'] = this.context;
|
|
163
|
+
this.context['$job'] = this.context;
|
|
166
164
|
}
|
|
167
165
|
bindJobMetadataPaths() {
|
|
168
166
|
return serializer_1.MDATA_SYMBOLS.JOB.KEYS.map((key) => `metadata/${key}`);
|
|
@@ -190,10 +188,6 @@ class Trigger extends activity_1.Activity {
|
|
|
190
188
|
throw new errors_1.DuplicateJobError(jobId);
|
|
191
189
|
}
|
|
192
190
|
}
|
|
193
|
-
/**
|
|
194
|
-
* Registers this job as a dependent of the parent job; when the
|
|
195
|
-
* parent job is interrupted, this job will be interrupted
|
|
196
|
-
*/
|
|
197
191
|
async registerJobDependency(multi) {
|
|
198
192
|
const depKey = this.config.stats?.parent ?? this.context.metadata.pj;
|
|
199
193
|
let resolvedDepKey = depKey ? pipe_1.Pipe.resolve(depKey, this.context) : '';
|
|
@@ -11,7 +11,6 @@ class Worker extends activity_1.Activity {
|
|
|
11
11
|
constructor(config, data, metadata, hook, engine, context) {
|
|
12
12
|
super(config, data, metadata, hook, engine, context);
|
|
13
13
|
}
|
|
14
|
-
//******** INITIAL ENTRY POINT (A) ********//
|
|
15
14
|
async process() {
|
|
16
15
|
this.logger.debug('worker-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
|
|
17
16
|
let telemetry;
|
|
@@ -20,15 +19,12 @@ class Worker extends activity_1.Activity {
|
|
|
20
19
|
telemetry = new telemetry_1.TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
|
|
21
20
|
telemetry.startActivitySpan(this.leg);
|
|
22
21
|
this.mapInputData();
|
|
23
|
-
//save state and authorize reentry
|
|
24
22
|
const multi = this.store.getMulti();
|
|
25
|
-
//todo: await this.registerTimeout();
|
|
26
23
|
const messageId = await this.execActivity(multi);
|
|
27
24
|
await collator_1.CollatorService.authorizeReentry(this, multi);
|
|
28
25
|
await this.setState(multi);
|
|
29
26
|
await this.setStatus(0, multi);
|
|
30
27
|
const multiResponse = await multi.exec();
|
|
31
|
-
//telemetry
|
|
32
28
|
telemetry.mapActivityAttributes();
|
|
33
29
|
const jobStatus = this.resolveStatus(multiResponse);
|
|
34
30
|
telemetry.setActivityAttributes({
|
|
@@ -6,40 +6,13 @@ import { Activity } from '../activities/activity';
|
|
|
6
6
|
import { Cycle } from '../activities/cycle';
|
|
7
7
|
declare class CollatorService {
|
|
8
8
|
static targetLength: number;
|
|
9
|
-
/**
|
|
10
|
-
* Upon re/entry, verify that the job status is active
|
|
11
|
-
*/
|
|
12
9
|
static assertJobActive(status: number, jobId: string, activityId: string): void;
|
|
13
|
-
/**
|
|
14
|
-
* returns the dimensional address (dad) for the target; due
|
|
15
|
-
* to the nature of the notary system, the dad for leg 2 entry
|
|
16
|
-
* must target the `0` index while leg 2 exit must target the
|
|
17
|
-
* current index (0)
|
|
18
|
-
*/
|
|
19
10
|
static getDimensionalAddress(activity: Activity, isEntry?: boolean): Record<string, string>;
|
|
20
|
-
/**
|
|
21
|
-
* resolves the dimensional address for the
|
|
22
|
-
* ancestor in the graph to go back to. this address
|
|
23
|
-
* is determined by trimming the last digits from
|
|
24
|
-
* the `dad` (including the target).
|
|
25
|
-
* the target activity index is then set to `0`, so that
|
|
26
|
-
* the origin node can be queried for approval/entry.
|
|
27
|
-
*/
|
|
28
11
|
static resolveReentryDimension(activity: Cycle): string;
|
|
29
12
|
static notarizeEntry(activity: Activity, multi?: RedisMulti): Promise<number>;
|
|
30
13
|
static authorizeReentry(activity: Activity, multi?: RedisMulti): Promise<number>;
|
|
31
14
|
static notarizeEarlyExit(activity: Activity, multi?: RedisMulti): Promise<number>;
|
|
32
15
|
static notarizeEarlyCompletion(activity: Activity, multi?: RedisMulti): Promise<number>;
|
|
33
|
-
/**
|
|
34
|
-
* verifies both the concrete and synthetic keys for the activity; concrete keys
|
|
35
|
-
* exist in the original model and are effectively the 'real' keys. In reality,
|
|
36
|
-
* hook activities are atomized during compilation to create a synthetic DAG that
|
|
37
|
-
* is used to track the status of the graph in a distributed environment. The
|
|
38
|
-
* synthetic key represents different dimensional realities and is used to
|
|
39
|
-
* track re-entry overages (it distinguishes between the original and re-entry).
|
|
40
|
-
* The essential challenge is: is this a re-entry that is purposeful in
|
|
41
|
-
* order to induce cycles, or is the re-entry due to a failure in the system?
|
|
42
|
-
*/
|
|
43
16
|
static notarizeReentry(activity: Activity, guid: string, multi?: RedisMulti): Promise<number>;
|
|
44
17
|
static notarizeContinuation(activity: Activity, multi?: RedisMulti): Promise<number>;
|
|
45
18
|
static notarizeCompletion(activity: Activity, multi?: RedisMulti): Promise<number>;
|
|
@@ -48,56 +21,13 @@ declare class CollatorService {
|
|
|
48
21
|
static isDuplicate(num: number, targetDigitIndex: number): boolean;
|
|
49
22
|
static isInactive(num: number): boolean;
|
|
50
23
|
static isPrimed(amount: number, leg: ActivityDuplex): boolean;
|
|
51
|
-
/**
|
|
52
|
-
* During compilation, the graphs are compiled into structures necessary
|
|
53
|
-
* for distributed processing; these are referred to as 'synthetic DAGs',
|
|
54
|
-
* because they are not part of the original graph, but are used to track
|
|
55
|
-
* the status of the graph in a distributed environment. This check ensures
|
|
56
|
-
* that the 'synthetic key' is not a duplicate. (which is different than
|
|
57
|
-
* saying the 'key' is not a duplicate)
|
|
58
|
-
*/
|
|
59
24
|
static verifySyntheticInteger(amount: number): void;
|
|
60
25
|
static verifyInteger(amount: number, leg: ActivityDuplex, stage: CollationStage): void;
|
|
61
26
|
static getDimensionsById(ancestors: string[], dad: string): Record<string, string>;
|
|
62
|
-
/**
|
|
63
|
-
* All non-trigger activities are assigned a status seed by their parent
|
|
64
|
-
*/
|
|
65
27
|
static getSeed(): string;
|
|
66
|
-
/**
|
|
67
|
-
* All trigger activities are assigned a status seed in a completed state
|
|
68
|
-
*/
|
|
69
28
|
static getTriggerSeed(): string;
|
|
70
|
-
/**
|
|
71
|
-
* entry point for compiler-type activities. This is called by the compiler
|
|
72
|
-
* to bind the sorted activity IDs to the trigger activity. These are then used
|
|
73
|
-
* at runtime by the activities to track job/activity status.
|
|
74
|
-
* @param graphs
|
|
75
|
-
*/
|
|
76
29
|
static compile(graphs: HotMeshGraph[]): void;
|
|
77
|
-
/**
|
|
78
|
-
* binds the ancestor array to each activity.
|
|
79
|
-
* Used in conjunction with the dimensional
|
|
80
|
-
* address (dad). If dad is `,0,1,0,0` and the
|
|
81
|
-
* ancestor array is `['t1', 'a1', 'a2']` for
|
|
82
|
-
* activity 'a3', then the SAVED DAD
|
|
83
|
-
* will always have the trailing
|
|
84
|
-
* 0's removed. This ensures that the addressing
|
|
85
|
-
* remains consistent even if the graph changes.
|
|
86
|
-
* id DAD SAVED DAD
|
|
87
|
-
* * t1 => ,0 => [empty]
|
|
88
|
-
* * a1 => ,0,1 => ,0,1
|
|
89
|
-
* * a2 => ,0,1,0 => ,0,1
|
|
90
|
-
* * a3 => ,0,1,0,0 => ,0,1
|
|
91
|
-
*
|
|
92
|
-
*/
|
|
93
30
|
static bindAncestorArray(graphs: HotMeshGraph[]): void;
|
|
94
|
-
/**
|
|
95
|
-
* All activities exist on a dimensional plane. Zero
|
|
96
|
-
* is the default. A value of
|
|
97
|
-
* `AxY,0,0,0,0,1,0,0` would reflect that
|
|
98
|
-
* an ancestor activity was dimensionalized beyond
|
|
99
|
-
* the default.
|
|
100
|
-
*/
|
|
101
31
|
static getDimensionalSeed(index?: number): string;
|
|
102
32
|
}
|
|
103
33
|
export { CollatorService };
|
|
@@ -4,20 +4,11 @@ exports.CollatorService = void 0;
|
|
|
4
4
|
const errors_1 = require("../../modules/errors");
|
|
5
5
|
const collator_1 = require("../../types/collator");
|
|
6
6
|
class CollatorService {
|
|
7
|
-
/**
|
|
8
|
-
* Upon re/entry, verify that the job status is active
|
|
9
|
-
*/
|
|
10
7
|
static assertJobActive(status, jobId, activityId) {
|
|
11
8
|
if (status <= 0) {
|
|
12
9
|
throw new errors_1.InactiveJobError(jobId, status, activityId);
|
|
13
10
|
}
|
|
14
11
|
}
|
|
15
|
-
/**
|
|
16
|
-
* returns the dimensional address (dad) for the target; due
|
|
17
|
-
* to the nature of the notary system, the dad for leg 2 entry
|
|
18
|
-
* must target the `0` index while leg 2 exit must target the
|
|
19
|
-
* current index (0)
|
|
20
|
-
*/
|
|
21
12
|
static getDimensionalAddress(activity, isEntry = false) {
|
|
22
13
|
let dad = activity.context.metadata.dad || activity.metadata.dad;
|
|
23
14
|
if (isEntry && dad && activity.leg === 2) {
|
|
@@ -25,62 +16,37 @@ class CollatorService {
|
|
|
25
16
|
}
|
|
26
17
|
return CollatorService.getDimensionsById([...activity.config.ancestors, activity.metadata.aid], dad);
|
|
27
18
|
}
|
|
28
|
-
/**
|
|
29
|
-
* resolves the dimensional address for the
|
|
30
|
-
* ancestor in the graph to go back to. this address
|
|
31
|
-
* is determined by trimming the last digits from
|
|
32
|
-
* the `dad` (including the target).
|
|
33
|
-
* the target activity index is then set to `0`, so that
|
|
34
|
-
* the origin node can be queried for approval/entry.
|
|
35
|
-
*/
|
|
36
19
|
static resolveReentryDimension(activity) {
|
|
37
20
|
const targetActivityId = activity.config.ancestor;
|
|
38
21
|
const ancestors = activity.config.ancestors;
|
|
39
22
|
const ancestorIndex = ancestors.indexOf(targetActivityId);
|
|
40
|
-
const dimensions = activity.metadata.dad.split(',');
|
|
23
|
+
const dimensions = activity.metadata.dad.split(',');
|
|
41
24
|
dimensions.length = ancestorIndex + 1;
|
|
42
25
|
dimensions.push('0');
|
|
43
26
|
return dimensions.join(',');
|
|
44
27
|
}
|
|
45
28
|
static async notarizeEntry(activity, multi) {
|
|
46
|
-
//decrement by -100_000_000_000_000
|
|
47
29
|
const amount = await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, -100000000000000, this.getDimensionalAddress(activity), multi);
|
|
48
30
|
this.verifyInteger(amount, 1, 'enter');
|
|
49
31
|
return amount;
|
|
50
32
|
}
|
|
51
33
|
;
|
|
52
34
|
static async authorizeReentry(activity, multi) {
|
|
53
|
-
//set second digit to 8, allowing for re-entry
|
|
54
|
-
//decrement by -10_000_000_000_000
|
|
55
35
|
const amount = await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, -10000000000000, this.getDimensionalAddress(activity), multi);
|
|
56
36
|
return amount;
|
|
57
37
|
}
|
|
58
38
|
static async notarizeEarlyExit(activity, multi) {
|
|
59
|
-
//decrement the 2nd and 3rd digits to fully deactivate (`cycle` activities use this command to fully exit after leg 1) (should result in `888000000000000`)
|
|
60
39
|
return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, -11000000000000, this.getDimensionalAddress(activity), multi);
|
|
61
40
|
}
|
|
62
41
|
;
|
|
63
42
|
static async notarizeEarlyCompletion(activity, multi) {
|
|
64
|
-
//initialize both `possible` (1m) and `actualized` (1) zero dimension, while decrementing the 2nd
|
|
65
|
-
//3rd digit is optionally kept open if the activity might be used in a cycle
|
|
66
43
|
const decrement = activity.config.cycle ? 10000000000000 : 11000000000000;
|
|
67
44
|
return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, 1000001 - decrement, this.getDimensionalAddress(activity), multi);
|
|
68
45
|
}
|
|
69
46
|
;
|
|
70
|
-
/**
|
|
71
|
-
* verifies both the concrete and synthetic keys for the activity; concrete keys
|
|
72
|
-
* exist in the original model and are effectively the 'real' keys. In reality,
|
|
73
|
-
* hook activities are atomized during compilation to create a synthetic DAG that
|
|
74
|
-
* is used to track the status of the graph in a distributed environment. The
|
|
75
|
-
* synthetic key represents different dimensional realities and is used to
|
|
76
|
-
* track re-entry overages (it distinguishes between the original and re-entry).
|
|
77
|
-
* The essential challenge is: is this a re-entry that is purposeful in
|
|
78
|
-
* order to induce cycles, or is the re-entry due to a failure in the system?
|
|
79
|
-
*/
|
|
80
47
|
static async notarizeReentry(activity, guid, multi) {
|
|
81
48
|
const jid = activity.context.metadata.jid;
|
|
82
49
|
const localMulti = multi || activity.store.getMulti();
|
|
83
|
-
//increment by 1_000_000 (indicates re-entry and is used to drive the 'dimensional address' for adjacent activities (minus 1))
|
|
84
50
|
await activity.store.collate(jid, activity.metadata.aid, 1000000, this.getDimensionalAddress(activity, true), localMulti);
|
|
85
51
|
await activity.store.collateSynthetic(jid, guid, 1000000, localMulti);
|
|
86
52
|
const [_amountConcrete, _amountSynthetic] = await localMulti.exec();
|
|
@@ -92,13 +58,10 @@ class CollatorService {
|
|
|
92
58
|
}
|
|
93
59
|
;
|
|
94
60
|
static async notarizeContinuation(activity, multi) {
|
|
95
|
-
//keep open; actualize the leg2 dimension (+1)
|
|
96
61
|
return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, 1, this.getDimensionalAddress(activity), multi);
|
|
97
62
|
}
|
|
98
63
|
;
|
|
99
64
|
static async notarizeCompletion(activity, multi) {
|
|
100
|
-
//1) ALWAYS actualize leg2 dimension (+1)
|
|
101
|
-
//2) IF the activity is used in a cycle, don't close leg 2!
|
|
102
65
|
const decrement = activity.config.cycle ? 0 : 1000000000000;
|
|
103
66
|
return await activity.store.collate(activity.context.metadata.jid, activity.metadata.aid, 1 - decrement, this.getDimensionalAddress(activity), multi);
|
|
104
67
|
}
|
|
@@ -127,7 +90,6 @@ class CollatorService {
|
|
|
127
90
|
return this.getDigitAtIndex(num, 2) < 9;
|
|
128
91
|
}
|
|
129
92
|
static isPrimed(amount, leg) {
|
|
130
|
-
//activity entry is not allowed if paths not properly pre-set
|
|
131
93
|
if (leg == 1) {
|
|
132
94
|
return amount != -100000000000000;
|
|
133
95
|
}
|
|
@@ -136,23 +98,13 @@ class CollatorService {
|
|
|
136
98
|
this.getDigitAtIndex(amount, 1) < 9;
|
|
137
99
|
}
|
|
138
100
|
}
|
|
139
|
-
/**
|
|
140
|
-
* During compilation, the graphs are compiled into structures necessary
|
|
141
|
-
* for distributed processing; these are referred to as 'synthetic DAGs',
|
|
142
|
-
* because they are not part of the original graph, but are used to track
|
|
143
|
-
* the status of the graph in a distributed environment. This check ensures
|
|
144
|
-
* that the 'synthetic key' is not a duplicate. (which is different than
|
|
145
|
-
* saying the 'key' is not a duplicate)
|
|
146
|
-
*/
|
|
147
101
|
static verifySyntheticInteger(amount) {
|
|
148
102
|
const samount = amount.toString();
|
|
149
103
|
const isCompletedValue = parseInt(samount[samount.length - 1], 10);
|
|
150
104
|
if (isCompletedValue > 0) {
|
|
151
|
-
//already done error (ack/delete clearly failed; this is a duplicate)
|
|
152
105
|
throw new errors_1.CollationError(amount, 2, 'enter', collator_1.CollationFaultType.INACTIVE);
|
|
153
106
|
}
|
|
154
107
|
else if (amount >= 2000000) {
|
|
155
|
-
//duplicate synthetic key (todo: need to resolve/fix this!!)
|
|
156
108
|
throw new errors_1.CollationError(amount, 2, 'enter', collator_1.CollationFaultType.DUPLICATE);
|
|
157
109
|
}
|
|
158
110
|
}
|
|
@@ -190,11 +142,6 @@ class CollatorService {
|
|
|
190
142
|
}
|
|
191
143
|
}
|
|
192
144
|
static getDimensionsById(ancestors, dad) {
|
|
193
|
-
//ancestors is an ordered list of all ancestors, starting with the trigger (['t1', 'a1', 'a2'])
|
|
194
|
-
//dad is the dimensional address of the ancestors list (',0,5,3')
|
|
195
|
-
//loop through the ancestors list and create a map of the ancestor to the dimensional address.
|
|
196
|
-
//return { 't1': ',0', 'a1': ',0,5', 'a1': ',0,5,3', $ADJACENT: ',0,5,3,0' };
|
|
197
|
-
// `adjacent` is a special key that is used to track the dimensional address of adjacent activities
|
|
198
145
|
const map = { '$ADJACENT': `${dad},0` };
|
|
199
146
|
let dadStr = dad;
|
|
200
147
|
ancestors.reverse().forEach((ancestor) => {
|
|
@@ -203,43 +150,15 @@ class CollatorService {
|
|
|
203
150
|
});
|
|
204
151
|
return map;
|
|
205
152
|
}
|
|
206
|
-
/**
|
|
207
|
-
* All non-trigger activities are assigned a status seed by their parent
|
|
208
|
-
*/
|
|
209
153
|
static getSeed() {
|
|
210
154
|
return '999000000000000';
|
|
211
155
|
}
|
|
212
|
-
/**
|
|
213
|
-
* All trigger activities are assigned a status seed in a completed state
|
|
214
|
-
*/
|
|
215
156
|
static getTriggerSeed() {
|
|
216
157
|
return '888000001000001';
|
|
217
158
|
}
|
|
218
|
-
/**
|
|
219
|
-
* entry point for compiler-type activities. This is called by the compiler
|
|
220
|
-
* to bind the sorted activity IDs to the trigger activity. These are then used
|
|
221
|
-
* at runtime by the activities to track job/activity status.
|
|
222
|
-
* @param graphs
|
|
223
|
-
*/
|
|
224
159
|
static compile(graphs) {
|
|
225
160
|
CollatorService.bindAncestorArray(graphs);
|
|
226
161
|
}
|
|
227
|
-
/**
|
|
228
|
-
* binds the ancestor array to each activity.
|
|
229
|
-
* Used in conjunction with the dimensional
|
|
230
|
-
* address (dad). If dad is `,0,1,0,0` and the
|
|
231
|
-
* ancestor array is `['t1', 'a1', 'a2']` for
|
|
232
|
-
* activity 'a3', then the SAVED DAD
|
|
233
|
-
* will always have the trailing
|
|
234
|
-
* 0's removed. This ensures that the addressing
|
|
235
|
-
* remains consistent even if the graph changes.
|
|
236
|
-
* id DAD SAVED DAD
|
|
237
|
-
* * t1 => ,0 => [empty]
|
|
238
|
-
* * a1 => ,0,1 => ,0,1
|
|
239
|
-
* * a2 => ,0,1,0 => ,0,1
|
|
240
|
-
* * a3 => ,0,1,0,0 => ,0,1
|
|
241
|
-
*
|
|
242
|
-
*/
|
|
243
162
|
static bindAncestorArray(graphs) {
|
|
244
163
|
graphs.forEach((graph) => {
|
|
245
164
|
const ancestors = {};
|
|
@@ -255,21 +174,12 @@ class CollatorService {
|
|
|
255
174
|
dfs(transition.to, [...parentList, node]);
|
|
256
175
|
});
|
|
257
176
|
};
|
|
258
|
-
// Start the DFS traversal
|
|
259
177
|
dfs(startingNode, []);
|
|
260
178
|
});
|
|
261
179
|
}
|
|
262
|
-
/**
|
|
263
|
-
* All activities exist on a dimensional plane. Zero
|
|
264
|
-
* is the default. A value of
|
|
265
|
-
* `AxY,0,0,0,0,1,0,0` would reflect that
|
|
266
|
-
* an ancestor activity was dimensionalized beyond
|
|
267
|
-
* the default.
|
|
268
|
-
*/
|
|
269
180
|
static getDimensionalSeed(index = 0) {
|
|
270
181
|
return `,${index}`;
|
|
271
182
|
}
|
|
272
183
|
}
|
|
273
184
|
exports.CollatorService = CollatorService;
|
|
274
|
-
//max int digit count that supports `hincrby`
|
|
275
185
|
CollatorService.targetLength = 15;
|