@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.
Files changed (182) hide show
  1. package/README.md +1 -1
  2. package/build/modules/enums.js +1 -10
  3. package/build/modules/key.d.ts +0 -38
  4. package/build/modules/key.js +4 -46
  5. package/build/modules/utils.d.ts +0 -8
  6. package/build/modules/utils.js +0 -14
  7. package/build/package.json +11 -4
  8. package/build/services/activities/activity.d.ts +0 -28
  9. package/build/services/activities/activity.js +1 -46
  10. package/build/services/activities/await.js +0 -4
  11. package/build/services/activities/cycle.d.ts +0 -7
  12. package/build/services/activities/cycle.js +1 -16
  13. package/build/services/activities/hook.d.ts +0 -6
  14. package/build/services/activities/hook.js +2 -12
  15. package/build/services/activities/interrupt.js +0 -8
  16. package/build/services/activities/signal.d.ts +0 -6
  17. package/build/services/activities/signal.js +0 -15
  18. package/build/services/activities/trigger.d.ts +0 -4
  19. package/build/services/activities/trigger.js +1 -7
  20. package/build/services/activities/worker.js +0 -4
  21. package/build/services/collator/index.d.ts +0 -70
  22. package/build/services/collator/index.js +1 -91
  23. package/build/services/compiler/deployer.js +6 -38
  24. package/build/services/compiler/index.d.ts +0 -15
  25. package/build/services/compiler/index.js +0 -20
  26. package/build/services/compiler/validator.d.ts +0 -3
  27. package/build/services/compiler/validator.js +0 -25
  28. package/build/services/connector/clients/ioredis.d.ts +2 -2
  29. package/build/services/connector/clients/ioredis.js +0 -2
  30. package/build/services/connector/clients/redis.d.ts +4 -4
  31. package/build/services/connector/clients/redis.js +1 -3
  32. package/build/services/connector/index.d.ts +1 -1
  33. package/build/services/connector/index.js +0 -2
  34. package/build/services/durable/client.d.ts +1 -26
  35. package/build/services/durable/client.js +0 -56
  36. package/build/services/durable/exporter.d.ts +0 -22
  37. package/build/services/durable/exporter.js +1 -30
  38. package/build/services/durable/handle.d.ts +0 -36
  39. package/build/services/durable/handle.js +0 -46
  40. package/build/services/durable/index.d.ts +0 -4
  41. package/build/services/durable/index.js +0 -4
  42. package/build/services/durable/schemas/factory.d.ts +0 -29
  43. package/build/services/durable/schemas/factory.js +0 -29
  44. package/build/services/durable/search.d.ts +1 -36
  45. package/build/services/durable/search.js +56 -56
  46. package/build/services/durable/worker.js +2 -22
  47. package/build/services/durable/workflow.d.ts +0 -114
  48. package/build/services/durable/workflow.js +1 -141
  49. package/build/services/engine/index.d.ts +1 -6
  50. package/build/services/engine/index.js +1 -43
  51. package/build/services/exporter/index.d.ts +0 -27
  52. package/build/services/exporter/index.js +0 -33
  53. package/build/services/hotmesh/index.d.ts +2 -2
  54. package/build/services/hotmesh/index.js +1 -9
  55. package/build/services/logger/index.js +0 -2
  56. package/build/services/mapper/index.d.ts +0 -14
  57. package/build/services/mapper/index.js +0 -14
  58. package/build/services/pipe/functions/date.d.ts +0 -7
  59. package/build/services/pipe/functions/date.js +0 -7
  60. package/build/services/pipe/functions/math.js +0 -2
  61. package/build/services/pipe/index.d.ts +0 -15
  62. package/build/services/pipe/index.js +2 -23
  63. package/build/services/quorum/index.d.ts +0 -7
  64. package/build/services/quorum/index.js +0 -21
  65. package/build/services/reporter/index.d.ts +0 -5
  66. package/build/services/reporter/index.js +0 -9
  67. package/build/services/router/index.d.ts +0 -9
  68. package/build/services/router/index.js +2 -38
  69. package/build/services/serializer/index.js +7 -26
  70. package/build/services/store/cache.d.ts +0 -18
  71. package/build/services/store/cache.js +0 -18
  72. package/build/services/store/clients/ioredis.d.ts +1 -1
  73. package/build/services/store/clients/ioredis.js +0 -1
  74. package/build/services/store/clients/redis.d.ts +1 -1
  75. package/build/services/store/index.d.ts +0 -55
  76. package/build/services/store/index.js +5 -81
  77. package/build/services/stream/clients/ioredis.d.ts +1 -1
  78. package/build/services/stream/clients/ioredis.js +1 -4
  79. package/build/services/stream/clients/redis.d.ts +1 -1
  80. package/build/services/sub/clients/ioredis.d.ts +1 -1
  81. package/build/services/sub/clients/redis.d.ts +1 -1
  82. package/build/services/task/index.d.ts +0 -9
  83. package/build/services/task/index.js +0 -31
  84. package/build/services/telemetry/index.d.ts +0 -7
  85. package/build/services/telemetry/index.js +1 -13
  86. package/build/services/worker/index.d.ts +0 -4
  87. package/build/services/worker/index.js +2 -6
  88. package/build/types/activity.d.ts +0 -81
  89. package/build/types/durable.d.ts +26 -177
  90. package/build/types/exporter.d.ts +0 -13
  91. package/build/types/hotmesh.d.ts +4 -16
  92. package/build/types/hotmesh.js +0 -3
  93. package/build/types/index.d.ts +4 -6
  94. package/build/types/index.js +4 -3
  95. package/build/types/job.d.ts +1 -86
  96. package/build/types/pipe.d.ts +0 -65
  97. package/build/types/quorum.d.ts +15 -10
  98. package/build/types/redis.d.ts +225 -7
  99. package/build/types/redis.js +9 -0
  100. package/build/types/stream.d.ts +0 -58
  101. package/build/types/stream.js +0 -4
  102. package/package.json +11 -4
  103. package/types/durable.ts +131 -4
  104. package/types/hotmesh.ts +3 -6
  105. package/types/index.ts +23 -10
  106. package/types/job.ts +1 -1
  107. package/types/quorum.ts +22 -0
  108. package/types/redis.ts +267 -18
  109. package/build/types/ioredisclient.d.ts +0 -5
  110. package/build/types/ioredisclient.js +0 -5
  111. package/build/types/redisclient.d.ts +0 -26
  112. package/build/types/redisclient.js +0 -2
  113. package/modules/enums.ts +0 -62
  114. package/modules/errors.ts +0 -280
  115. package/modules/key.ts +0 -101
  116. package/modules/storage.ts +0 -3
  117. package/modules/utils.ts +0 -242
  118. package/services/activities/activity.ts +0 -589
  119. package/services/activities/await.ts +0 -113
  120. package/services/activities/cycle.ts +0 -115
  121. package/services/activities/hook.ts +0 -197
  122. package/services/activities/index.ts +0 -19
  123. package/services/activities/interrupt.ts +0 -172
  124. package/services/activities/signal.ts +0 -148
  125. package/services/activities/trigger.ts +0 -295
  126. package/services/activities/worker.ts +0 -107
  127. package/services/collator/README.md +0 -102
  128. package/services/collator/index.ts +0 -291
  129. package/services/compiler/deployer.ts +0 -504
  130. package/services/compiler/index.ts +0 -98
  131. package/services/compiler/validator.ts +0 -158
  132. package/services/connector/clients/ioredis.ts +0 -57
  133. package/services/connector/clients/redis.ts +0 -72
  134. package/services/connector/index.ts +0 -42
  135. package/services/durable/client.ts +0 -266
  136. package/services/durable/connection.ts +0 -10
  137. package/services/durable/exporter.ts +0 -232
  138. package/services/durable/handle.ts +0 -160
  139. package/services/durable/index.ts +0 -27
  140. package/services/durable/schemas/factory.ts +0 -2358
  141. package/services/durable/search.ts +0 -196
  142. package/services/durable/worker.ts +0 -401
  143. package/services/durable/workflow.ts +0 -557
  144. package/services/engine/index.ts +0 -761
  145. package/services/exporter/index.ts +0 -146
  146. package/services/hotmesh/index.ts +0 -237
  147. package/services/logger/index.ts +0 -79
  148. package/services/mapper/index.ts +0 -89
  149. package/services/pipe/functions/array.ts +0 -78
  150. package/services/pipe/functions/bitwise.ts +0 -27
  151. package/services/pipe/functions/conditional.ts +0 -35
  152. package/services/pipe/functions/date.ts +0 -220
  153. package/services/pipe/functions/index.ts +0 -27
  154. package/services/pipe/functions/json.ts +0 -11
  155. package/services/pipe/functions/logical.ts +0 -11
  156. package/services/pipe/functions/math.ts +0 -217
  157. package/services/pipe/functions/number.ts +0 -75
  158. package/services/pipe/functions/object.ts +0 -98
  159. package/services/pipe/functions/string.ts +0 -86
  160. package/services/pipe/functions/symbol.ts +0 -39
  161. package/services/pipe/functions/unary.ts +0 -19
  162. package/services/pipe/index.ts +0 -216
  163. package/services/quorum/index.ts +0 -319
  164. package/services/reporter/index.ts +0 -387
  165. package/services/router/index.ts +0 -426
  166. package/services/serializer/README.md +0 -10
  167. package/services/serializer/index.ts +0 -285
  168. package/services/store/cache.ts +0 -172
  169. package/services/store/clients/ioredis.ts +0 -145
  170. package/services/store/clients/redis.ts +0 -191
  171. package/services/store/index.ts +0 -1091
  172. package/services/stream/clients/ioredis.ts +0 -157
  173. package/services/stream/clients/redis.ts +0 -158
  174. package/services/stream/index.ts +0 -58
  175. package/services/sub/clients/ioredis.ts +0 -83
  176. package/services/sub/clients/redis.ts +0 -74
  177. package/services/sub/index.ts +0 -25
  178. package/services/task/index.ts +0 -250
  179. package/services/telemetry/index.ts +0 -273
  180. package/services/worker/index.ts +0 -248
  181. package/types/ioredisclient.ts +0 -10
  182. 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 };