@hotmeshio/hotmesh 0.0.55 → 0.0.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/build/modules/enums.js +1 -10
  2. package/build/modules/key.d.ts +0 -38
  3. package/build/modules/key.js +4 -46
  4. package/build/modules/utils.d.ts +0 -8
  5. package/build/modules/utils.js +0 -14
  6. package/build/package.json +11 -4
  7. package/build/services/activities/activity.d.ts +0 -28
  8. package/build/services/activities/activity.js +1 -46
  9. package/build/services/activities/await.js +0 -4
  10. package/build/services/activities/cycle.d.ts +0 -7
  11. package/build/services/activities/cycle.js +1 -16
  12. package/build/services/activities/hook.d.ts +0 -6
  13. package/build/services/activities/hook.js +2 -12
  14. package/build/services/activities/interrupt.js +0 -8
  15. package/build/services/activities/signal.d.ts +0 -6
  16. package/build/services/activities/signal.js +0 -15
  17. package/build/services/activities/trigger.d.ts +0 -4
  18. package/build/services/activities/trigger.js +1 -7
  19. package/build/services/activities/worker.js +0 -4
  20. package/build/services/collator/index.d.ts +0 -70
  21. package/build/services/collator/index.js +1 -91
  22. package/build/services/compiler/deployer.js +6 -38
  23. package/build/services/compiler/index.d.ts +0 -15
  24. package/build/services/compiler/index.js +0 -20
  25. package/build/services/compiler/validator.d.ts +0 -3
  26. package/build/services/compiler/validator.js +0 -25
  27. package/build/services/connector/clients/ioredis.d.ts +2 -2
  28. package/build/services/connector/clients/ioredis.js +0 -2
  29. package/build/services/connector/clients/redis.d.ts +4 -4
  30. package/build/services/connector/clients/redis.js +1 -3
  31. package/build/services/connector/index.d.ts +1 -1
  32. package/build/services/connector/index.js +0 -2
  33. package/build/services/durable/client.d.ts +1 -26
  34. package/build/services/durable/client.js +0 -56
  35. package/build/services/durable/exporter.d.ts +0 -22
  36. package/build/services/durable/exporter.js +1 -30
  37. package/build/services/durable/handle.d.ts +0 -36
  38. package/build/services/durable/handle.js +0 -46
  39. package/build/services/durable/index.d.ts +0 -4
  40. package/build/services/durable/index.js +0 -4
  41. package/build/services/durable/schemas/factory.d.ts +0 -29
  42. package/build/services/durable/schemas/factory.js +0 -29
  43. package/build/services/durable/search.d.ts +1 -36
  44. package/build/services/durable/search.js +57 -56
  45. package/build/services/durable/worker.js +2 -22
  46. package/build/services/durable/workflow.d.ts +0 -114
  47. package/build/services/durable/workflow.js +1 -141
  48. package/build/services/engine/index.d.ts +1 -6
  49. package/build/services/engine/index.js +1 -43
  50. package/build/services/exporter/index.d.ts +0 -27
  51. package/build/services/exporter/index.js +0 -33
  52. package/build/services/hotmesh/index.d.ts +2 -2
  53. package/build/services/hotmesh/index.js +1 -9
  54. package/build/services/logger/index.js +0 -2
  55. package/build/services/mapper/index.d.ts +0 -14
  56. package/build/services/mapper/index.js +0 -14
  57. package/build/services/pipe/functions/date.d.ts +0 -7
  58. package/build/services/pipe/functions/date.js +0 -7
  59. package/build/services/pipe/functions/math.js +0 -2
  60. package/build/services/pipe/index.d.ts +0 -15
  61. package/build/services/pipe/index.js +2 -23
  62. package/build/services/quorum/index.d.ts +0 -7
  63. package/build/services/quorum/index.js +0 -21
  64. package/build/services/reporter/index.d.ts +0 -5
  65. package/build/services/reporter/index.js +0 -9
  66. package/build/services/router/index.d.ts +0 -9
  67. package/build/services/router/index.js +2 -38
  68. package/build/services/serializer/index.js +7 -26
  69. package/build/services/store/cache.d.ts +0 -18
  70. package/build/services/store/cache.js +0 -18
  71. package/build/services/store/clients/ioredis.d.ts +1 -1
  72. package/build/services/store/clients/ioredis.js +0 -1
  73. package/build/services/store/clients/redis.d.ts +1 -1
  74. package/build/services/store/index.d.ts +0 -55
  75. package/build/services/store/index.js +5 -81
  76. package/build/services/stream/clients/ioredis.d.ts +1 -1
  77. package/build/services/stream/clients/ioredis.js +1 -4
  78. package/build/services/stream/clients/redis.d.ts +1 -1
  79. package/build/services/sub/clients/ioredis.d.ts +1 -1
  80. package/build/services/sub/clients/redis.d.ts +1 -1
  81. package/build/services/task/index.d.ts +0 -9
  82. package/build/services/task/index.js +0 -31
  83. package/build/services/telemetry/index.d.ts +0 -7
  84. package/build/services/telemetry/index.js +1 -13
  85. package/build/services/worker/index.d.ts +0 -4
  86. package/build/services/worker/index.js +2 -6
  87. package/build/types/activity.d.ts +0 -81
  88. package/build/types/durable.d.ts +25 -177
  89. package/build/types/exporter.d.ts +0 -13
  90. package/build/types/hotmesh.d.ts +4 -16
  91. package/build/types/hotmesh.js +0 -3
  92. package/build/types/index.d.ts +4 -6
  93. package/build/types/index.js +4 -3
  94. package/build/types/job.d.ts +1 -86
  95. package/build/types/pipe.d.ts +0 -65
  96. package/build/types/quorum.d.ts +15 -10
  97. package/build/types/redis.d.ts +225 -7
  98. package/build/types/redis.js +9 -0
  99. package/build/types/stream.d.ts +0 -58
  100. package/build/types/stream.js +0 -4
  101. package/package.json +11 -4
  102. package/types/durable.ts +121 -3
  103. package/types/hotmesh.ts +3 -6
  104. package/types/index.ts +23 -10
  105. package/types/job.ts +1 -1
  106. package/types/quorum.ts +22 -0
  107. package/types/redis.ts +267 -18
  108. package/build/types/ioredisclient.d.ts +0 -5
  109. package/build/types/ioredisclient.js +0 -5
  110. package/build/types/redisclient.d.ts +0 -26
  111. package/build/types/redisclient.js +0 -2
  112. package/modules/enums.ts +0 -62
  113. package/modules/errors.ts +0 -280
  114. package/modules/key.ts +0 -101
  115. package/modules/storage.ts +0 -3
  116. package/modules/utils.ts +0 -242
  117. package/services/activities/activity.ts +0 -589
  118. package/services/activities/await.ts +0 -113
  119. package/services/activities/cycle.ts +0 -115
  120. package/services/activities/hook.ts +0 -197
  121. package/services/activities/index.ts +0 -19
  122. package/services/activities/interrupt.ts +0 -172
  123. package/services/activities/signal.ts +0 -148
  124. package/services/activities/trigger.ts +0 -295
  125. package/services/activities/worker.ts +0 -107
  126. package/services/collator/README.md +0 -102
  127. package/services/collator/index.ts +0 -291
  128. package/services/compiler/deployer.ts +0 -504
  129. package/services/compiler/index.ts +0 -98
  130. package/services/compiler/validator.ts +0 -158
  131. package/services/connector/clients/ioredis.ts +0 -57
  132. package/services/connector/clients/redis.ts +0 -72
  133. package/services/connector/index.ts +0 -42
  134. package/services/durable/client.ts +0 -266
  135. package/services/durable/connection.ts +0 -10
  136. package/services/durable/exporter.ts +0 -232
  137. package/services/durable/handle.ts +0 -160
  138. package/services/durable/index.ts +0 -27
  139. package/services/durable/schemas/factory.ts +0 -2358
  140. package/services/durable/search.ts +0 -196
  141. package/services/durable/worker.ts +0 -401
  142. package/services/durable/workflow.ts +0 -557
  143. package/services/engine/index.ts +0 -761
  144. package/services/exporter/index.ts +0 -146
  145. package/services/hotmesh/index.ts +0 -237
  146. package/services/logger/index.ts +0 -79
  147. package/services/mapper/index.ts +0 -89
  148. package/services/pipe/functions/array.ts +0 -78
  149. package/services/pipe/functions/bitwise.ts +0 -27
  150. package/services/pipe/functions/conditional.ts +0 -35
  151. package/services/pipe/functions/date.ts +0 -220
  152. package/services/pipe/functions/index.ts +0 -27
  153. package/services/pipe/functions/json.ts +0 -11
  154. package/services/pipe/functions/logical.ts +0 -11
  155. package/services/pipe/functions/math.ts +0 -217
  156. package/services/pipe/functions/number.ts +0 -75
  157. package/services/pipe/functions/object.ts +0 -98
  158. package/services/pipe/functions/string.ts +0 -86
  159. package/services/pipe/functions/symbol.ts +0 -39
  160. package/services/pipe/functions/unary.ts +0 -19
  161. package/services/pipe/index.ts +0 -216
  162. package/services/quorum/index.ts +0 -319
  163. package/services/reporter/index.ts +0 -387
  164. package/services/router/index.ts +0 -426
  165. package/services/serializer/README.md +0 -10
  166. package/services/serializer/index.ts +0 -285
  167. package/services/store/cache.ts +0 -172
  168. package/services/store/clients/ioredis.ts +0 -145
  169. package/services/store/clients/redis.ts +0 -191
  170. package/services/store/index.ts +0 -1091
  171. package/services/stream/clients/ioredis.ts +0 -157
  172. package/services/stream/clients/redis.ts +0 -158
  173. package/services/stream/index.ts +0 -58
  174. package/services/sub/clients/ioredis.ts +0 -83
  175. package/services/sub/clients/redis.ts +0 -74
  176. package/services/sub/index.ts +0 -25
  177. package/services/task/index.ts +0 -250
  178. package/services/telemetry/index.ts +0 -273
  179. package/services/worker/index.ts +0 -248
  180. package/types/ioredisclient.ts +0 -10
  181. package/types/redisclient.ts +0 -30
@@ -1,115 +0,0 @@
1
- import {
2
- GenerationalError,
3
- GetStateError,
4
- InactiveJobError } from '../../modules/errors';
5
- import { guid } from '../../modules/utils';
6
- import { CollatorService } from '../collator';
7
- import { EngineService } from '../engine';
8
- import { Activity } from './activity';
9
- import {
10
- ActivityData,
11
- ActivityMetadata,
12
- ActivityType,
13
- CycleActivity } from '../../types/activity';
14
- import { JobState } from '../../types/job';
15
- import { MultiResponseFlags, RedisMulti } from '../../types/redis';
16
- import { StreamData } from '../../types/stream';
17
- import { TelemetryService } from '../telemetry';
18
-
19
- class Cycle extends Activity {
20
- config: CycleActivity;
21
-
22
- constructor(
23
- config: ActivityType,
24
- data: ActivityData,
25
- metadata: ActivityMetadata,
26
- hook: ActivityData | null,
27
- engine: EngineService,
28
- context?: JobState) {
29
- super(config, data, metadata, hook, engine, context);
30
- }
31
-
32
-
33
- //******** LEG 1 ENTRY ********//
34
- async process(): Promise<string> {
35
- this.logger.debug('cycle-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
36
- let telemetry: TelemetryService;
37
- try {
38
- await this.verifyEntry();
39
-
40
- telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
41
- telemetry.startActivitySpan(this.leg);
42
- this.mapInputData();
43
-
44
- //set state/status
45
- let multi = this.store.getMulti();
46
- await this.setState(multi);
47
- await this.setStatus(0, multi); //leg 1 never changes job status
48
- const multiResponse = await multi.exec() as MultiResponseFlags;
49
- telemetry.mapActivityAttributes();
50
- const jobStatus = this.resolveStatus(multiResponse);
51
-
52
- //cycle the target ancestor
53
- multi = this.store.getMulti();
54
- const messageId = await this.cycleAncestorActivity(multi);
55
- telemetry.setActivityAttributes({
56
- 'app.activity.mid': messageId,
57
- 'app.job.jss': jobStatus
58
- });
59
-
60
- //exit early (`Cycle` activities only execute Leg 1)
61
- await CollatorService.notarizeEarlyExit(this, multi);
62
- await multi.exec() as MultiResponseFlags;
63
-
64
- return this.context.metadata.aid;
65
- } catch (error) {
66
- if (error instanceof InactiveJobError) {
67
- this.logger.error('cycle-inactive-job-error', { ...error });
68
- return;
69
- } else if (error instanceof GenerationalError) {
70
- this.logger.info('process-event-generational-job-error', { ...error });
71
- return;
72
- } else if (error instanceof GetStateError) {
73
- this.logger.error('cycle-get-state-error', { ...error });
74
- return;
75
- } else {
76
- this.logger.error('cycle-process-error', { ...error });
77
- }
78
- telemetry.setActivityError(error.message);
79
- throw error;
80
- } finally {
81
- telemetry?.endActivitySpan();
82
- this.logger.debug('cycle-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
83
- }
84
- }
85
-
86
- /**
87
- * Trigger the target ancestor to execute in a cycle,
88
- * without violating the constraints of the DAG. Immutable
89
- * `individual activity state` will execute in a new dimensional
90
- * thread while `shared job state` can change. This
91
- * pattern allows for retries without violating the DAG.
92
- */
93
- async cycleAncestorActivity(multi: RedisMulti): Promise<string> {
94
- //Cycle activity L1 is a standin for the target ancestor L1.
95
- //Input data mapping (mapInputData) allows for the
96
- //next dimensonal thread to execute with different
97
- //input data than the current dimensional thread
98
- this.mapInputData();
99
- const streamData: StreamData = {
100
- metadata: {
101
- guid: guid(),
102
- jid: this.context.metadata.jid,
103
- gid: this.context.metadata.gid,
104
- dad: CollatorService.resolveReentryDimension(this),
105
- aid: this.config.ancestor,
106
- spn: this.context['$self'].output.metadata?.l1s,
107
- trc: this.context.metadata.trc,
108
- },
109
- data: this.context.data
110
- };
111
- return (await this.engine.router?.publishMessage(null, streamData, multi)) as string;
112
- }
113
- }
114
-
115
- export { Cycle };
@@ -1,197 +0,0 @@
1
- import {
2
- GenerationalError,
3
- GetStateError,
4
- InactiveJobError } from '../../modules/errors';
5
- import { Activity } from './activity';
6
- import { CollatorService } from '../collator';
7
- import { EngineService } from '../engine';
8
- import { Pipe } from '../pipe';
9
- import { TaskService } from '../task';
10
- import { TelemetryService } from '../telemetry';
11
- import {
12
- ActivityData,
13
- ActivityMetadata,
14
- ActivityType,
15
- HookActivity } from '../../types/activity';
16
- import { HookRule } from '../../types/hook';
17
- import { JobState, JobStatus } from '../../types/job';
18
- import {
19
- MultiResponseFlags,
20
- RedisMulti } from '../../types/redis';
21
- import { StringScalarType } from '../../types/serializer';
22
- import { StreamCode, StreamStatus } from '../../types/stream';
23
-
24
- /**
25
- * Supports `signal hook`, `time hook`, and `cycle hook` patterns
26
- */
27
- class Hook extends Activity {
28
- config: HookActivity;
29
-
30
- constructor(
31
- config: ActivityType,
32
- data: ActivityData,
33
- metadata: ActivityMetadata,
34
- hook: ActivityData | null,
35
- engine: EngineService,
36
- context?: JobState) {
37
- super(config, data, metadata, hook, engine, context);
38
- }
39
-
40
- //******** INITIAL ENTRY POINT (A) ********//
41
- async process(): Promise<string> {
42
- this.logger.debug('hook-process', {
43
- jid: this.context.metadata.jid,
44
- gid: this.context.metadata.gid,
45
- aid: this.metadata.aid,
46
- });
47
- let telemetry: TelemetryService;
48
-
49
- try {
50
- await this.verifyEntry();
51
-
52
- telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
53
- telemetry.startActivitySpan(this.leg);
54
-
55
- if (this.doesHook()) {
56
- //sleep and wait to awaken upon a signal
57
- await this.doHook(telemetry);
58
- } else {
59
- //end the activity and transition to its children
60
- await this.doPassThrough(telemetry);
61
- }
62
-
63
- return this.context.metadata.aid;
64
- } catch (error) {
65
- if (error instanceof InactiveJobError) {
66
- this.logger.error('hook-inactive-job-error', { ...error });
67
- return;
68
- } else if (error instanceof GenerationalError) {
69
- this.logger.info('process-event-generational-job-error', { ...error });
70
- return;
71
- } else if (error instanceof GetStateError) {
72
- this.logger.error('hook-get-state-error', { ...error });
73
- return;
74
- } else {
75
- this.logger.error('hook-process-error', { ...error });
76
- }
77
- telemetry.setActivityError(error.message);
78
- throw error;
79
- } finally {
80
- telemetry?.endActivitySpan();
81
- this.logger.debug('hook-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
82
- }
83
- }
84
-
85
- /**
86
- * does this activity use a time-hook or web-hook
87
- */
88
- doesHook(): boolean {
89
- if (this.config.sleep) {
90
- const duration = Pipe.resolve(
91
- this.config.sleep,
92
- this.context,
93
- );
94
- return !isNaN(duration) && Number(duration) > 0
95
- }
96
- return !!this.config.hook?.topic;
97
- }
98
-
99
- async doHook(telemetry: TelemetryService) {
100
- const multi = this.store.getMulti();
101
- await this.registerHook(multi);
102
- this.mapOutputData();
103
- this.mapJobData();
104
- await this.setState(multi);
105
- await CollatorService.authorizeReentry(this, multi);
106
-
107
- await this.setStatus(0, multi);
108
- await multi.exec();
109
- telemetry.mapActivityAttributes();
110
- }
111
-
112
- async doPassThrough(telemetry: TelemetryService) {
113
- const multi = this.store.getMulti();
114
- let multiResponse: MultiResponseFlags;
115
-
116
- this.adjacencyList = await this.filterAdjacent();
117
- this.mapOutputData();
118
- this.mapJobData();
119
- await this.setState(multi);
120
- await CollatorService.notarizeEarlyCompletion(this, multi);
121
-
122
- await this.setStatus(this.adjacencyList.length - 1, multi);
123
- multiResponse = await multi.exec() as MultiResponseFlags;
124
- telemetry.mapActivityAttributes();
125
- const jobStatus = this.resolveStatus(multiResponse);
126
- const attrs: StringScalarType = { 'app.job.jss': jobStatus };
127
- const messageIds = await this.transition(this.adjacencyList, jobStatus);
128
- if (messageIds.length) {
129
- attrs['app.activity.mids'] = messageIds.join(',')
130
- }
131
- telemetry.setActivityAttributes(attrs);
132
- }
133
-
134
- async getHookRule(topic: string): Promise<HookRule | undefined> {
135
- const rules = await this.store.getHookRules();
136
- return rules?.[topic]?.[0] as HookRule;
137
- }
138
-
139
- async registerHook(multi?: RedisMulti): Promise<string | void> {
140
- if (this.config.hook?.topic) {
141
- return await this.engine.taskService.registerWebHook(
142
- this.config.hook.topic,
143
- this.context,
144
- this.resolveDad(),
145
- multi
146
- );
147
- } else if (this.config.sleep) {
148
- const duration = Pipe.resolve(
149
- this.config.sleep,
150
- this.context,
151
- );
152
- await this.engine.taskService.registerTimeHook(
153
- this.context.metadata.jid,
154
- this.context.metadata.gid,
155
- `${this.metadata.aid}${this.metadata.dad || ''}`,
156
- 'sleep',
157
- duration,
158
- this.metadata.dad || '',
159
- );
160
- return this.context.metadata.jid;
161
- }
162
- }
163
-
164
- //******** SIGNAL RE-ENTRY POINT ********//
165
- async processWebHookEvent(status: StreamStatus = StreamStatus.SUCCESS, code: StreamCode = 200): Promise<JobStatus | void> {
166
- this.logger.debug('hook-process-web-hook-event', {
167
- topic: this.config.hook.topic,
168
- aid: this.metadata.aid,
169
- status,
170
- code,
171
- });
172
- const taskService = new TaskService(this.store, this.logger);
173
- const data = { ...this.data };
174
- const signal = await taskService.processWebHookSignal(this.config.hook.topic, data);
175
- if (signal) {
176
- const [jobId, _aid, dad, gId] = signal;
177
- this.context.metadata.jid = jobId;
178
- this.context.metadata.gid = gId;
179
- this.context.metadata.dad = dad;
180
- await this.processEvent(status, code, 'hook');
181
- if (code === 200) {
182
- await taskService.deleteWebHookSignal(this.config.hook.topic, data);
183
- } //else => 202/keep alive
184
- } //else => already resolved
185
- }
186
-
187
- async processTimeHookEvent(jobId: string): Promise<JobStatus | void> {
188
- this.logger.debug('hook-process-time-hook-event', {
189
- jid: jobId,
190
- gid: this.context.metadata.gid,
191
- aid: this.metadata.aid
192
- });
193
- await this.processEvent(StreamStatus.SUCCESS, 200, 'hook');
194
- }
195
- }
196
-
197
- export { Hook };
@@ -1,19 +0,0 @@
1
- import { Activity } from './activity';
2
- import { Await } from './await';
3
- import { Cycle } from './cycle';
4
- import { Hook } from './hook';
5
- import { Interrupt } from './interrupt';
6
- import { Signal } from './signal';
7
- import { Trigger } from './trigger';
8
- import { Worker } from './worker';
9
-
10
- export default {
11
- activity: Activity,
12
- await: Await,
13
- cycle: Cycle,
14
- hook: Hook,
15
- interrupt: Interrupt,
16
- signal: Signal,
17
- trigger: Trigger,
18
- worker: Worker,
19
- };
@@ -1,172 +0,0 @@
1
- import {
2
- GenerationalError,
3
- GetStateError,
4
- InactiveJobError } from '../../modules/errors';
5
- import { CollatorService } from '../collator';
6
- import { Activity } from './activity';
7
- import { EngineService } from '../engine';
8
- import { Pipe } from '../pipe';
9
- import { TelemetryService } from '../telemetry';
10
- import {
11
- ActivityData,
12
- ActivityMetadata,
13
- ActivityType,
14
- InterruptActivity } from '../../types/activity';
15
- import { JobInterruptOptions, JobState } from '../../types/job';
16
- import { MultiResponseFlags } from '../../types/redis';
17
-
18
- class Interrupt extends Activity {
19
- config: InterruptActivity;
20
-
21
- constructor(
22
- config: ActivityType,
23
- data: ActivityData,
24
- metadata: ActivityMetadata,
25
- hook: ActivityData | null,
26
- engine: EngineService,
27
- context?: JobState
28
- ) {
29
- super(config, data, metadata, hook, engine, context);
30
- }
31
-
32
-
33
- //******** LEG 1 ENTRY ********//
34
- async process(): Promise<string> {
35
- this.logger.debug('interrupt-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
36
- let telemetry: TelemetryService;
37
- try {
38
- await this.verifyEntry();
39
-
40
- telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
41
- telemetry.startActivitySpan(this.leg);
42
-
43
- if (this.isInterruptingSelf()) {
44
- await this.interruptSelf(telemetry);
45
- } else {
46
- await this.interruptAnother(telemetry);
47
- }
48
- } catch (error) {
49
- if (error instanceof InactiveJobError) {
50
- this.logger.error('interrupt-inactive-job-error', { ...error });
51
- return;
52
- } else if (error instanceof GenerationalError) {
53
- this.logger.info('process-event-generational-job-error', { ...error });
54
- return;
55
- } else if (error instanceof GetStateError) {
56
- this.logger.error('interrupt-get-state-error', { ...error });
57
- return;
58
- } else {
59
- this.logger.error('interrupt-process-error', { ...error });
60
- }
61
- telemetry.setActivityError(error.message);
62
- throw error;
63
- } finally {
64
- telemetry?.endActivitySpan();
65
- this.logger.debug('interrupt-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
66
- }
67
- }
68
-
69
- async interruptSelf(telemetry: TelemetryService): Promise<string> {
70
- // Apply final updates to THIS job's state
71
- if (this.config.job?.maps) {
72
- this.mapJobData();
73
- await this.setState();
74
- }
75
-
76
- // Interrupt THIS job
77
- const messageId = await this.interrupt();
78
-
79
- // Notarize completion and log
80
- telemetry.mapActivityAttributes();
81
- const multi = this.store.getMulti();
82
- await CollatorService.notarizeEarlyCompletion(this, multi);
83
- await this.setStatus(-1, multi);
84
- const multiResponse = await multi.exec() as MultiResponseFlags;
85
- const jobStatus = this.resolveStatus(multiResponse);
86
- telemetry.setActivityAttributes({
87
- 'app.activity.mid': messageId,
88
- 'app.job.jss': jobStatus
89
- });
90
-
91
- return this.context.metadata.aid;
92
- }
93
-
94
- async interruptAnother(telemetry: TelemetryService): Promise<string> {
95
- // Interrupt ANOTHER job
96
- const messageId = await this.interrupt();
97
- const attrs = { 'app.activity.mid': messageId };
98
-
99
- // Apply updates to THIS job's state
100
- telemetry.mapActivityAttributes();
101
- this.adjacencyList = await this.filterAdjacent();
102
- if (this.config.job?.maps || this.config.output?.maps) {
103
- this.mapOutputData();
104
- this.mapJobData();
105
- const multi = this.store.getMulti();
106
- await this.setState(multi);
107
- }
108
-
109
- // Notarize completion
110
- const multi = this.store.getMulti();
111
- await CollatorService.notarizeEarlyCompletion(this, multi);
112
- await this.setStatus(this.adjacencyList.length - 1, multi);
113
- const multiResponse = await multi.exec() as MultiResponseFlags;
114
- const jobStatus = this.resolveStatus(multiResponse);
115
- attrs['app.job.jss'] = jobStatus;
116
-
117
- // Transition next generation and log
118
- const messageIds = await this.transition(this.adjacencyList, jobStatus);
119
- if (messageIds.length) {
120
- attrs['app.activity.mids'] = messageIds.join(',');
121
- }
122
- telemetry.setActivityAttributes(attrs);
123
-
124
- return this.context.metadata.aid;
125
- }
126
-
127
- isInterruptingSelf(): boolean {
128
- if (!this.config.target) {
129
- return true;
130
- }
131
- const resolvedJob = Pipe.resolve(this.config.target, this.context);
132
- return resolvedJob == this.context.metadata.jid;
133
- }
134
-
135
- resolveInterruptOptions(): JobInterruptOptions {
136
- return {
137
- reason: this.config.reason !== undefined
138
- ? Pipe.resolve(this.config.reason, this.context)
139
- : undefined,
140
- throw: this.config.throw !== undefined
141
- ? Pipe.resolve(this.config.throw, this.context)
142
- : undefined,
143
- descend: this.config.descend !== undefined
144
- ? Pipe.resolve(this.config.descend, this.context)
145
- : undefined,
146
- code: this.config.code !== undefined
147
- ? Pipe.resolve(this.config.code, this.context)
148
- : undefined,
149
- expire: this.config.expire !== undefined
150
- ? Pipe.resolve(this.config.expire, this.context)
151
- : undefined,
152
- stack: this.config.stack !== undefined
153
- ? Pipe.resolve(this.config.stack, this.context)
154
- : undefined,
155
- };
156
- }
157
-
158
- async interrupt(): Promise<string> {
159
- const options = this.resolveInterruptOptions();
160
- return await this.engine.interrupt(
161
- this.config.topic !== undefined
162
- ? Pipe.resolve(this.config.topic, this.context)
163
- : this.context.metadata.tpc,
164
- this.config.target !== undefined
165
- ? Pipe.resolve(this.config.target, this.context)
166
- : this.context.metadata.jid,
167
- options as JobInterruptOptions,
168
- );
169
- }
170
- }
171
-
172
- export { Interrupt };
@@ -1,148 +0,0 @@
1
- import {
2
- GenerationalError,
3
- GetStateError,
4
- InactiveJobError } from '../../modules/errors';
5
- import { Activity } from './activity';
6
- import { CollatorService } from '../collator';
7
- import { EngineService } from '../engine';
8
- import { MapperService } from '../mapper';
9
- import { Pipe } from '../pipe';
10
- import { TelemetryService } from '../telemetry';
11
- import {
12
- ActivityData,
13
- ActivityMetadata,
14
- ActivityType,
15
- SignalActivity } from '../../types/activity';
16
- import { JobState } from '../../types/job';
17
- import { MultiResponseFlags } from '../../types/redis';
18
- import { StringScalarType } from '../../types/serializer';
19
- import { JobStatsInput } from '../../types/stats';
20
-
21
- class Signal extends Activity {
22
- config: SignalActivity;
23
-
24
- constructor(
25
- config: ActivityType,
26
- data: ActivityData,
27
- metadata: ActivityMetadata,
28
- hook: ActivityData | null,
29
- engine: EngineService,
30
- context?: JobState) {
31
- super(config, data, metadata, hook, engine, context);
32
- }
33
-
34
-
35
- //******** LEG 1 ENTRY ********//
36
- async process(): Promise<string> {
37
- this.logger.debug('signal-process', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
38
- let telemetry: TelemetryService;
39
- try {
40
- await this.verifyEntry();
41
-
42
- telemetry = new TelemetryService(this.engine.appId, this.config, this.metadata, this.context);
43
- telemetry.startActivitySpan(this.leg);
44
-
45
- //save state and notarize early completion (signals only run leg1)
46
- const multi = this.store.getMulti();
47
- this.adjacencyList = await this.filterAdjacent();
48
- this.mapOutputData();
49
- this.mapJobData();
50
- await this.setState(multi);
51
- await CollatorService.notarizeEarlyCompletion(this, multi);
52
- await this.setStatus(this.adjacencyList.length - 1, multi);
53
- const multiResponse = await multi.exec() as MultiResponseFlags;
54
-
55
- //todo: this should execute BEFORE the status is decremented
56
- if (this.config.subtype === 'all') {
57
- await this.hookAll();
58
- } else {
59
- await this.hookOne();
60
- }
61
-
62
- //transition to adjacent activities
63
- const jobStatus = this.resolveStatus(multiResponse);
64
- const attrs: StringScalarType = { 'app.job.jss': jobStatus };
65
- const messageIds = await this.transition(this.adjacencyList, jobStatus);
66
- if (messageIds.length) {
67
- attrs['app.activity.mids'] = messageIds.join(',')
68
- }
69
- telemetry.mapActivityAttributes();
70
- telemetry.setActivityAttributes(attrs);
71
-
72
- return this.context.metadata.aid;
73
- } catch (error) {
74
- if (error instanceof InactiveJobError) {
75
- this.logger.error('signal-inactive-job-error', { ...error });
76
- return;
77
- } else if (error instanceof GenerationalError) {
78
- this.logger.info('process-event-generational-job-error', { ...error });
79
- return;
80
- } else if (error instanceof GetStateError) {
81
- this.logger.error('signal-get-state-error', { ...error });
82
- return;
83
- } else {
84
- this.logger.error('signal-process-error', { ...error });
85
- }
86
- telemetry.setActivityError(error.message);
87
- throw error;
88
- } finally {
89
- telemetry?.endActivitySpan();
90
- this.logger.debug('signal-process-end', { jid: this.context.metadata.jid, gid: this.context.metadata.gid, aid: this.metadata.aid });
91
- }
92
- }
93
-
94
- mapSignalData(): Record<string, any> {
95
- if(this.config.signal?.maps) {
96
- const mapper = new MapperService(this.config.signal.maps, this.context);
97
- return mapper.mapRules();
98
- }
99
- }
100
-
101
- mapResolverData(): Record<string, any> {
102
- if(this.config.resolver?.maps) {
103
- const mapper = new MapperService(this.config.resolver.maps, this.context);
104
- return mapper.mapRules();
105
- }
106
- }
107
-
108
- /**
109
- * The signal activity will hook one
110
- */
111
- async hookOne(): Promise<string> {
112
- const topic = Pipe.resolve(this.config.topic, this.context);
113
- const signalInputData = this.mapSignalData();
114
- const status = Pipe.resolve(this.config.status, this.context);
115
- const code = Pipe.resolve(this.config.code, this.context);
116
- return await this.engine.hook(topic, signalInputData, status, code);
117
- }
118
-
119
- /**
120
- * The signal activity will hook all paused jobs that share the same job key.
121
- */
122
- async hookAll(): Promise<string[]> {
123
- //prep 1) generate `input signal data` (essentially the webhook payload)
124
- const signalInputData = this.mapSignalData();
125
-
126
- //prep 2) generate data that resolves the job key (per the YAML config)
127
- const keyResolverData = this.mapResolverData() as JobStatsInput;
128
- if (this.config.scrub) {
129
- //self-clean the indexes upon use if configured
130
- keyResolverData.scrub = true;
131
- }
132
-
133
- //prep 3) jobKeys can contain multiple indexes (per the YAML config)
134
- const key_name = Pipe.resolve(this.config.key_name, this.context);
135
- const key_value = Pipe.resolve(this.config.key_value, this.context);
136
- const indexQueryFacets = [`${key_name}:${key_value}`];
137
-
138
- //execute: `hookAll` will now resume all paused jobs that share the same job key
139
- return await this.engine.hookAll(
140
- this.config.topic,
141
- signalInputData,
142
- keyResolverData,
143
- indexQueryFacets
144
- );
145
- }
146
- }
147
-
148
- export { Signal };