@hatchet-dev/typescript-sdk 0.0.1 → 0.0.3

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 (109) hide show
  1. package/README.md +2 -3
  2. package/dist/{hatchet/clients → clients}/admin/admin-client.d.ts +2 -2
  3. package/dist/{hatchet/clients → clients}/admin/admin-client.js +2 -2
  4. package/dist/{hatchet/clients → clients}/dispatcher/action-listener.d.ts +3 -3
  5. package/dist/{hatchet/clients → clients}/dispatcher/action-listener.js +2 -2
  6. package/dist/{hatchet/clients → clients}/dispatcher/dispatcher-client.d.ts +3 -3
  7. package/dist/{hatchet/clients → clients}/dispatcher/dispatcher-client.js +2 -2
  8. package/dist/{hatchet/clients → clients}/event/event-client.d.ts +3 -3
  9. package/dist/{hatchet/clients → clients}/event/event-client.js +2 -2
  10. package/dist/{hatchet/clients → clients}/hatchet-client/hatchet-client.d.ts +6 -6
  11. package/dist/{hatchet/clients → clients}/hatchet-client/hatchet-client.js +6 -6
  12. package/dist/{hatchet/clients → clients}/worker/worker.d.ts +6 -6
  13. package/dist/{hatchet/clients → clients}/worker/worker.js +5 -5
  14. package/dist/index.d.ts +2 -0
  15. package/dist/{hatchet/index.js → index.js} +1 -1
  16. package/dist/protoc/events/index.js +17 -0
  17. package/dist/sdk.d.ts +2 -0
  18. package/dist/{hatchet/sdk.js → sdk.js} +1 -1
  19. package/dist/{hatchet/step.js → step.js} +1 -1
  20. package/dist/{hatchet/util → util}/config-loader/config-loader.d.ts +1 -1
  21. package/dist/{hatchet/util → util}/config-loader/config-loader.js +1 -1
  22. package/package.json +8 -5
  23. package/.eslintrc.json +0 -36
  24. package/.prettierrc.json +0 -6
  25. package/dist/hatchet/clients/admin/admin-client.test.d.ts +0 -1
  26. package/dist/hatchet/clients/admin/admin-client.test.js +0 -101
  27. package/dist/hatchet/clients/dispatcher/action-listener.test.d.ts +0 -4
  28. package/dist/hatchet/clients/dispatcher/action-listener.test.js +0 -277
  29. package/dist/hatchet/clients/dispatcher/dispatcher-client.test.d.ts +0 -1
  30. package/dist/hatchet/clients/dispatcher/dispatcher-client.test.js +0 -99
  31. package/dist/hatchet/clients/event/event-client.test.d.ts +0 -1
  32. package/dist/hatchet/clients/event/event-client.test.js +0 -60
  33. package/dist/hatchet/clients/hatchet-client/hatchet-client.test.d.ts +0 -2
  34. package/dist/hatchet/clients/hatchet-client/hatchet-client.test.js +0 -135
  35. package/dist/hatchet/clients/worker/worker.test.d.ts +0 -1
  36. package/dist/hatchet/clients/worker/worker.test.js +0 -256
  37. package/dist/hatchet/index.d.ts +0 -2
  38. package/dist/hatchet/sdk.d.ts +0 -2
  39. package/dist/hatchet/util/config-loader/config-loader.test.d.ts +0 -1
  40. package/dist/hatchet/util/config-loader/config-loader.test.js +0 -72
  41. package/dist/hatchet/util/hatchet-promise/hatchet-promise.test.d.ts +0 -1
  42. package/dist/hatchet/util/hatchet-promise/hatchet-promise.test.js +0 -40
  43. package/examples/dag-worker.ts +0 -55
  44. package/examples/example-event.ts +0 -7
  45. package/examples/simple-worker.ts +0 -39
  46. package/generate-protoc.sh +0 -10
  47. package/hatchet/clients/admin/admin-client.test.ts +0 -116
  48. package/hatchet/clients/admin/admin-client.ts +0 -43
  49. package/hatchet/clients/dispatcher/action-listener.test.ts +0 -270
  50. package/hatchet/clients/dispatcher/action-listener.ts +0 -91
  51. package/hatchet/clients/dispatcher/dispatcher-client.test.ts +0 -111
  52. package/hatchet/clients/dispatcher/dispatcher-client.ts +0 -47
  53. package/hatchet/clients/event/event-client.test.ts +0 -72
  54. package/hatchet/clients/event/event-client.ts +0 -32
  55. package/hatchet/clients/hatchet-client/client-config.ts +0 -22
  56. package/hatchet/clients/hatchet-client/fixtures/.hatchet-invalid.yaml +0 -6
  57. package/hatchet/clients/hatchet-client/fixtures/.hatchet.yaml +0 -8
  58. package/hatchet/clients/hatchet-client/hatchet-client.test.ts +0 -162
  59. package/hatchet/clients/hatchet-client/hatchet-client.ts +0 -136
  60. package/hatchet/clients/hatchet-client/index.ts +0 -2
  61. package/hatchet/clients/worker/index.ts +0 -1
  62. package/hatchet/clients/worker/worker.test.ts +0 -347
  63. package/hatchet/clients/worker/worker.ts +0 -229
  64. package/hatchet/index.ts +0 -3
  65. package/hatchet/sdk.ts +0 -3
  66. package/hatchet/step.ts +0 -48
  67. package/hatchet/util/config-loader/config-loader.test.ts +0 -79
  68. package/hatchet/util/config-loader/config-loader.ts +0 -91
  69. package/hatchet/util/config-loader/fixtures/.hatchet-invalid.yaml +0 -6
  70. package/hatchet/util/config-loader/fixtures/.hatchet.yaml +0 -8
  71. package/hatchet/util/config-loader/index.ts +0 -1
  72. package/hatchet/util/errors/hatchet-error.ts +0 -8
  73. package/hatchet/util/hatchet-promise/hatchet-promise.test.ts +0 -32
  74. package/hatchet/util/hatchet-promise/hatchet-promise.ts +0 -13
  75. package/hatchet/util/logger/index.ts +0 -1
  76. package/hatchet/util/logger/logger.ts +0 -44
  77. package/hatchet/util/sleep.ts +0 -6
  78. package/hatchet/workflow.ts +0 -30
  79. package/jest.config.ts +0 -205
  80. package/protoc/dispatcher/dispatcher.ts +0 -1101
  81. package/protoc/dispatcher/index.ts +0 -1
  82. package/protoc/events/events.ts +0 -519
  83. package/protoc/google/protobuf/timestamp.ts +0 -210
  84. package/protoc/google/protobuf/wrappers.ts +0 -657
  85. package/protoc/workflows/index.ts +0 -1
  86. package/protoc/workflows/workflows.ts +0 -2158
  87. package/tsconfig.json +0 -120
  88. /package/dist/{hatchet/clients → clients}/hatchet-client/client-config.d.ts +0 -0
  89. /package/dist/{hatchet/clients → clients}/hatchet-client/client-config.js +0 -0
  90. /package/dist/{hatchet/clients → clients}/hatchet-client/index.d.ts +0 -0
  91. /package/dist/{hatchet/clients → clients}/hatchet-client/index.js +0 -0
  92. /package/dist/{hatchet/clients → clients}/worker/index.d.ts +0 -0
  93. /package/dist/{hatchet/clients → clients}/worker/index.js +0 -0
  94. /package/{protoc/events/index.ts → dist/protoc/events/index.d.ts} +0 -0
  95. /package/dist/{hatchet/step.d.ts → step.d.ts} +0 -0
  96. /package/dist/{hatchet/util → util}/config-loader/index.d.ts +0 -0
  97. /package/dist/{hatchet/util → util}/config-loader/index.js +0 -0
  98. /package/dist/{hatchet/util → util}/errors/hatchet-error.d.ts +0 -0
  99. /package/dist/{hatchet/util → util}/errors/hatchet-error.js +0 -0
  100. /package/dist/{hatchet/util → util}/hatchet-promise/hatchet-promise.d.ts +0 -0
  101. /package/dist/{hatchet/util → util}/hatchet-promise/hatchet-promise.js +0 -0
  102. /package/dist/{hatchet/util → util}/logger/index.d.ts +0 -0
  103. /package/dist/{hatchet/util → util}/logger/index.js +0 -0
  104. /package/dist/{hatchet/util → util}/logger/logger.d.ts +0 -0
  105. /package/dist/{hatchet/util → util}/logger/logger.js +0 -0
  106. /package/dist/{hatchet/util → util}/sleep.d.ts +0 -0
  107. /package/dist/{hatchet/util → util}/sleep.js +0 -0
  108. /package/dist/{hatchet/workflow.d.ts → workflow.d.ts} +0 -0
  109. /package/dist/{hatchet/workflow.js → workflow.js} +0 -0
@@ -1,162 +0,0 @@
1
- import { ChannelCredentials, createChannel, createClientFactory } from 'nice-grpc';
2
- import { HatchetClient } from './hatchet-client';
3
-
4
- export const mockChannel = createChannel('localhost:50051');
5
- export const mockFactory = createClientFactory();
6
-
7
- describe('Client', () => {
8
- beforeEach(() => {
9
- process.env.HATCHET_CLIENT_TOKEN = 'TOKEN_ENV';
10
- });
11
-
12
- it('should load from environment variables', () => {
13
- const hatchet = new HatchetClient(
14
- {
15
- token: 'TOKEN_ENV',
16
- host_port: 'HOST_PORT',
17
- log_level: 'OFF',
18
- tls_config: {
19
- cert_file: 'TLS_CERT_FILE',
20
- key_file: 'TLS_KEY_FILE',
21
- ca_file: 'TLS_ROOT_CA_FILE',
22
- server_name: 'TLS_SERVER_NAME',
23
- },
24
- },
25
- {
26
- credentials: ChannelCredentials.createInsecure(),
27
- }
28
- );
29
-
30
- expect(hatchet.config).toEqual({
31
- token: 'TOKEN_ENV',
32
- host_port: 'HOST_PORT',
33
- log_level: 'OFF',
34
- tls_config: {
35
- tls_strategy: 'tls',
36
- cert_file: 'TLS_CERT_FILE',
37
- key_file: 'TLS_KEY_FILE',
38
- ca_file: 'TLS_ROOT_CA_FILE',
39
- server_name: 'TLS_SERVER_NAME',
40
- },
41
- });
42
- });
43
-
44
- it('should throw an error if the config param is invalid', () => {
45
- expect(
46
- () =>
47
- new HatchetClient({
48
- host_port: 'HOST_PORT',
49
- tls_config: {
50
- tls_strategy: 'tls',
51
- cert_file: 'TLS_CERT_FILE',
52
- key_file: 'TLS_KEY_FILE',
53
- ca_file: 'TLS_ROOT_CA_FILE',
54
- // @ts-ignore
55
- server_name: undefined,
56
- },
57
- })
58
- ).toThrow();
59
- });
60
-
61
- it('should favor config param over yaml over env vars ', () => {
62
- const hatchet = new HatchetClient(
63
- {
64
- tls_config: {
65
- cert_file: 'TLS_CERT_FILE',
66
- key_file: 'TLS_KEY_FILE',
67
- ca_file: 'TLS_ROOT_CA_FILE',
68
- server_name: 'TLS_SERVER_NAME',
69
- },
70
- },
71
- {
72
- config_path: './fixtures/.hatchet.yaml',
73
- credentials: ChannelCredentials.createInsecure(),
74
- }
75
- );
76
-
77
- expect(hatchet.config).toEqual({
78
- token: 'TOKEN_YAML',
79
- host_port: 'HOST_PORT_YAML',
80
- log_level: 'INFO',
81
- tls_config: {
82
- tls_strategy: 'tls',
83
- cert_file: 'TLS_CERT_FILE',
84
- key_file: 'TLS_KEY_FILE',
85
- ca_file: 'TLS_ROOT_CA_FILE',
86
- server_name: 'TLS_SERVER_NAME',
87
- },
88
- });
89
- });
90
-
91
- describe('with_host_port', () => {
92
- it('should set the host_port', () => {
93
- const hatchet = HatchetClient.with_host_port(
94
- 'HOST',
95
- 1234,
96
- {
97
- token: 'TOKEN',
98
- tls_config: {
99
- tls_strategy: 'tls',
100
- cert_file: 'TLS_CERT_FILE',
101
- key_file: 'TLS_KEY_FILE',
102
- ca_file: 'TLS_ROOT_CA_FILE',
103
- server_name: 'TLS_SERVER_NAME',
104
- },
105
- },
106
- {
107
- credentials: ChannelCredentials.createInsecure(),
108
- }
109
- );
110
- expect(hatchet.config).toEqual({
111
- token: 'TOKEN',
112
- host_port: 'HOST:1234',
113
- log_level: 'INFO',
114
- tls_config: {
115
- tls_strategy: 'tls',
116
- cert_file: 'TLS_CERT_FILE',
117
- key_file: 'TLS_KEY_FILE',
118
- ca_file: 'TLS_ROOT_CA_FILE',
119
- server_name: 'TLS_SERVER_NAME',
120
- },
121
- });
122
- });
123
- });
124
-
125
- describe('Worker', () => {
126
- let hatchet: HatchetClient;
127
-
128
- beforeEach(() => {
129
- hatchet = new HatchetClient(
130
- {
131
- token: 'TOKEN',
132
- host_port: 'HOST_PORT',
133
- log_level: 'OFF',
134
- tls_config: {
135
- cert_file: 'TLS_CERT_FILE',
136
- key_file: 'TLS_KEY_FILE',
137
- ca_file: 'TLS_ROOT_CA_FILE',
138
- server_name: 'TLS_SERVER_NAME',
139
- },
140
- },
141
- {
142
- credentials: ChannelCredentials.createInsecure(),
143
- }
144
- );
145
- });
146
-
147
- describe('run', () => {
148
- xit('should start a worker', () => {
149
- const worker = hatchet.run('workflow1');
150
- expect(worker).toBeDefined();
151
- });
152
- });
153
-
154
- describe('worker', () => {
155
- it('should start a worker', () => {
156
- const worker = hatchet.worker('workflow1');
157
-
158
- expect(worker).toBeDefined();
159
- });
160
- });
161
- });
162
- });
@@ -1,136 +0,0 @@
1
- import { z } from 'zod';
2
- import { ConfigLoader } from '@util/config-loader';
3
- import { EventClient } from '@clients/event/event-client';
4
- import { DispatcherClient } from '@clients/dispatcher/dispatcher-client';
5
- import { AdminClient } from '@clients/admin/admin-client';
6
- import {
7
- CallOptions,
8
- Channel,
9
- ChannelCredentials,
10
- ClientMiddlewareCall,
11
- Metadata,
12
- createChannel,
13
- createClientFactory,
14
- } from 'nice-grpc';
15
- import { Workflow } from '@hatchet/workflow';
16
- import { Worker } from '@clients/worker';
17
- import Logger from '@hatchet/util/logger/logger';
18
- import { ClientConfig, ClientConfigSchema } from './client-config';
19
-
20
- export interface HatchetClientOptions {
21
- config_path?: string;
22
- credentials?: ChannelCredentials;
23
- }
24
-
25
- const addTokenMiddleware = (token: string) =>
26
- async function* _<Request, Response>(
27
- call: ClientMiddlewareCall<Request, Response>,
28
- options: CallOptions
29
- ) {
30
- const optionsWithAuth: CallOptions = {
31
- ...options,
32
- metadata: new Metadata({ authorization: `bearer ${token}` }),
33
- };
34
-
35
- if (!call.responseStream) {
36
- const response = yield* call.next(call.request, optionsWithAuth);
37
-
38
- return response;
39
- }
40
-
41
- for await (const response of call.next(call.request, optionsWithAuth)) {
42
- yield response;
43
- }
44
-
45
- return undefined;
46
- };
47
-
48
- export class HatchetClient {
49
- config: ClientConfig;
50
- credentials: ChannelCredentials;
51
- channel: Channel;
52
-
53
- event: EventClient;
54
- dispatcher: DispatcherClient;
55
- admin: AdminClient;
56
-
57
- logger: Logger;
58
-
59
- constructor(config?: Partial<ClientConfig>, options?: HatchetClientOptions) {
60
- // Initializes a new Client instance.
61
- // Loads config in the following order: config param > yaml file > env vars
62
-
63
- const loaded = ConfigLoader.load_client_config({
64
- path: options?.config_path,
65
- });
66
-
67
- try {
68
- const valid = ClientConfigSchema.parse({
69
- ...loaded,
70
- ...{ ...config, tls_config: { ...loaded.tls_config, ...config?.tls_config } },
71
- });
72
- this.config = valid;
73
- } catch (e) {
74
- if (e instanceof z.ZodError) {
75
- throw new Error(`Invalid client config: ${e.message}`);
76
- }
77
- throw e;
78
- }
79
-
80
- this.credentials =
81
- options?.credentials ?? ConfigLoader.createCredentials(this.config.tls_config);
82
-
83
- this.channel = createChannel(this.config.host_port, this.credentials, {
84
- 'grpc.ssl_target_name_override': this.config.tls_config.server_name,
85
- });
86
-
87
- const clientFactory = createClientFactory().use(addTokenMiddleware(this.config.token));
88
-
89
- this.event = new EventClient(this.config, this.channel, clientFactory);
90
- this.dispatcher = new DispatcherClient(this.config, this.channel, clientFactory);
91
- this.admin = new AdminClient(this.config, this.channel, clientFactory);
92
-
93
- this.logger = new Logger('HatchetClient', this.config.log_level);
94
-
95
- this.logger.info(`Initialized HatchetClient`);
96
- }
97
-
98
- static with_host_port(
99
- host: string,
100
- port: number,
101
- config?: Partial<ClientConfig>,
102
- options?: HatchetClientOptions
103
- ): HatchetClient {
104
- return new HatchetClient(
105
- {
106
- ...config,
107
- host_port: `${host}:${port}`,
108
- },
109
- options
110
- );
111
- }
112
-
113
- static init(config?: Partial<ClientConfig>, options?: HatchetClientOptions): HatchetClient {
114
- return new HatchetClient(config, options);
115
- }
116
-
117
- async run(workflow: string | Workflow): Promise<Worker> {
118
- const worker = await this.worker(workflow);
119
- worker.start();
120
- return worker;
121
- }
122
-
123
- async worker(workflow: string | Workflow): Promise<Worker> {
124
- const name = typeof workflow === 'string' ? workflow : workflow.id;
125
- const worker = new Worker(this, {
126
- name,
127
- });
128
-
129
- if (typeof workflow !== 'string') {
130
- await worker.register_workflow(workflow);
131
- return worker;
132
- }
133
-
134
- return worker;
135
- }
136
- }
@@ -1,2 +0,0 @@
1
- export * from './hatchet-client';
2
- export * from './client-config';
@@ -1 +0,0 @@
1
- export * from './worker';
@@ -1,347 +0,0 @@
1
- import { HatchetClient } from '@clients/hatchet-client';
2
- import { ActionEventType, ActionType, AssignedAction } from '@protoc/dispatcher';
3
- import { ActionListener } from '@clients/dispatcher/action-listener';
4
- import { ServerError, Status } from 'nice-grpc-common';
5
- import { mockListener } from '@clients/dispatcher/action-listener.test';
6
- import { never } from 'zod';
7
- import sleep from '@util/sleep';
8
- import { ChannelCredentials } from 'nice-grpc';
9
- import { Worker } from './worker';
10
- import { Context } from '@hatchet/step';
11
-
12
- type AssignActionMock = AssignedAction | Error;
13
-
14
- const mockStart: AssignActionMock = {
15
- tenantId: 'TENANT_ID',
16
- jobId: 'job1',
17
- jobName: 'Job One',
18
- jobRunId: 'run1',
19
- stepId: 'step1',
20
- stepRunId: 'runStep1',
21
- actionId: 'action1',
22
- actionType: ActionType.START_STEP_RUN,
23
- actionPayload: JSON.stringify('{"input": {"data": 1}}'),
24
- };
25
-
26
- const mockCancel: AssignActionMock = {
27
- ...mockStart,
28
- actionType: ActionType.CANCEL_STEP_RUN,
29
- };
30
-
31
- describe('Worker', () => {
32
- let hatchet: HatchetClient;
33
-
34
- beforeEach(() => {
35
- hatchet = new HatchetClient(
36
- {
37
- token: 'TOKEN',
38
- log_level: 'OFF',
39
- host_port: 'HOST_PORT',
40
- tls_config: {
41
- cert_file: 'TLS_CERT_FILE',
42
- key_file: 'TLS_KEY_FILE',
43
- ca_file: 'TLS_ROOT_CA_FILE',
44
- server_name: 'TLS_SERVER_NAME',
45
- },
46
- },
47
- {
48
- credentials: ChannelCredentials.createInsecure(),
49
- }
50
- );
51
- });
52
-
53
- describe('register_workflow', () => {
54
- it('should update the registry', async () => {
55
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
56
- const putWorkflowSpy = jest.spyOn(worker.client.admin, 'put_workflow').mockResolvedValue();
57
-
58
- const workflow = {
59
- id: 'workflow1',
60
- description: 'test',
61
- on: {
62
- event: 'user:create',
63
- },
64
- steps: [
65
- {
66
- name: 'step1',
67
- run: (ctx: any) => {
68
- return { test: 'test' };
69
- },
70
- },
71
- ],
72
- };
73
-
74
- await worker.register_workflow(workflow);
75
-
76
- expect(putWorkflowSpy).toHaveBeenCalledTimes(1);
77
-
78
- expect(worker.action_registry).toEqual({
79
- [`default:step1`]: workflow.steps[0].run,
80
- });
81
- });
82
- });
83
-
84
- describe('handle_start_step_run', () => {
85
- it('should start a step run', async () => {
86
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
87
-
88
- const putWorkflowSpy = jest.spyOn(worker.client.admin, 'put_workflow').mockResolvedValue();
89
-
90
- const getActionEventSpy = jest.spyOn(worker, 'get_action_event');
91
-
92
- const sendActionEventSpy = jest
93
- .spyOn(worker.client.dispatcher, 'send_action_event')
94
- .mockResolvedValue({
95
- tenantId: 'TENANT_ID',
96
- workerId: 'WORKER_ID',
97
- });
98
-
99
- const startSpy = jest.fn().mockReturnValue({ data: 4 });
100
-
101
- worker.action_registry = {
102
- [mockStart.actionId]: startSpy,
103
- };
104
-
105
- worker.handle_start_step_run(mockStart);
106
- await sleep(100);
107
-
108
- expect(startSpy).toHaveBeenCalledTimes(1);
109
-
110
- expect(getActionEventSpy).toHaveBeenNthCalledWith(
111
- 2,
112
- expect.anything(),
113
- ActionEventType.STEP_EVENT_TYPE_COMPLETED,
114
- { data: 4 }
115
- );
116
- expect(worker.futures[mockStart.stepRunId]).toBeUndefined();
117
- expect(sendActionEventSpy).toHaveBeenCalledTimes(2);
118
- });
119
-
120
- it('should fail gracefully', async () => {
121
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
122
-
123
- const getActionEventSpy = jest.spyOn(worker, 'get_action_event');
124
-
125
- const sendActionEventSpy = jest
126
- .spyOn(worker.client.dispatcher, 'send_action_event')
127
- .mockResolvedValue({
128
- tenantId: 'TENANT_ID',
129
- workerId: 'WORKER_ID',
130
- });
131
-
132
- const startSpy = jest.fn().mockRejectedValue(new Error('ERROR'));
133
-
134
- worker.action_registry = {
135
- [mockStart.actionId]: startSpy,
136
- };
137
-
138
- worker.handle_start_step_run(mockStart);
139
- await sleep(100);
140
-
141
- expect(startSpy).toHaveBeenCalledTimes(1);
142
- expect(getActionEventSpy).toHaveBeenNthCalledWith(
143
- 2,
144
- expect.anything(),
145
- ActionEventType.STEP_EVENT_TYPE_FAILED,
146
- expect.anything()
147
- );
148
- expect(worker.futures[mockStart.stepRunId]).toBeUndefined();
149
- expect(sendActionEventSpy).toHaveBeenCalledTimes(2);
150
- });
151
- });
152
-
153
- describe('handle_cancel_step_run', () => {
154
- it('should cancel a step run', () => {
155
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
156
-
157
- const cancelSpy = jest.fn().mockReturnValue(undefined);
158
-
159
- worker.futures = {
160
- [mockCancel.stepRunId]: {
161
- cancel: cancelSpy,
162
- } as any,
163
- };
164
-
165
- worker.handle_cancel_step_run(mockCancel);
166
-
167
- expect(cancelSpy).toHaveBeenCalledTimes(1);
168
- expect(worker.futures[mockCancel.stepRunId]).toBeUndefined();
169
- });
170
- });
171
-
172
- describe('exit_gracefully', () => {
173
- xit('should call exit_gracefully on SIGTERM', async () => {
174
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
175
-
176
- // the spy is not working and the test is killing the test process
177
- const exitSpy = jest.spyOn(worker, 'exit_gracefully').mockImplementationOnce(() => {
178
- throw new Error('Simulated error');
179
- });
180
-
181
- process.emit('SIGTERM', 'SIGTERM');
182
- expect(exitSpy).toHaveBeenCalledTimes(1);
183
- });
184
-
185
- xit('should call exit_gracefully on SIGINT', async () => {
186
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
187
-
188
- // This is killing the process (as it should) fix the spy at some point
189
- const exitSpy = jest.spyOn(worker, 'exit_gracefully').mockResolvedValue();
190
-
191
- process.emit('SIGINT', 'SIGINT');
192
- expect(exitSpy).toHaveBeenCalledTimes(1);
193
- });
194
-
195
- xit('should unregister the listener and exit', async () => {
196
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
197
-
198
- jest.spyOn(process, 'exit').mockImplementation((number) => {
199
- throw new Error(`EXIT ${number}`);
200
- }); // This is killing the process (as it should) fix the spy at some point
201
-
202
- const mockActionListener = new ActionListener(
203
- hatchet.dispatcher,
204
- mockListener([mockStart, mockStart, new ServerError(Status.CANCELLED, 'CANCELLED')]),
205
- 'WORKER_ID'
206
- );
207
-
208
- mockActionListener.unregister = jest.fn().mockResolvedValue(never());
209
- worker.listener = mockActionListener;
210
-
211
- expect(async () => {
212
- await worker.exit_gracefully();
213
- }).toThrow('EXIT 0');
214
- expect(mockActionListener.unregister).toHaveBeenCalledTimes(1);
215
- });
216
-
217
- it('should exit the process if handle_kill is true', async () => {
218
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
219
- const exitSpy = jest.spyOn(process, 'exit').mockReturnValue(undefined as never);
220
- await worker.exit_gracefully();
221
- expect(exitSpy).toHaveBeenCalledTimes(1);
222
- });
223
- });
224
-
225
- describe('start', () => {
226
- xit('should get actions and start runs', async () => {
227
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
228
-
229
- const startSpy = jest.spyOn(worker, 'handle_start_step_run').mockReturnValue();
230
- const cancelSpy = jest.spyOn(worker, 'handle_cancel_step_run').mockReturnValue();
231
-
232
- const mockActionListener = new ActionListener(
233
- hatchet.dispatcher,
234
- mockListener([mockStart, mockStart, new ServerError(Status.CANCELLED, 'CANCELLED')]),
235
- 'WORKER_ID'
236
- );
237
-
238
- const getActionListenerSpy = jest
239
- .spyOn(worker.client.dispatcher, 'get_action_listener')
240
- .mockResolvedValue(mockActionListener);
241
-
242
- await worker.start();
243
-
244
- expect(getActionListenerSpy).toHaveBeenCalledTimes(1);
245
- expect(startSpy).toHaveBeenCalledTimes(2);
246
- expect(cancelSpy).toHaveBeenCalledTimes(0);
247
- });
248
-
249
- it('should get actions and cancel runs', async () => {
250
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
251
-
252
- const startSpy = jest.spyOn(worker, 'handle_start_step_run').mockReturnValue();
253
- const cancelSpy = jest.spyOn(worker, 'handle_cancel_step_run').mockReturnValue();
254
-
255
- const mockActionListner = new ActionListener(
256
- hatchet.dispatcher,
257
- mockListener([mockStart, mockCancel, new ServerError(Status.CANCELLED, 'CANCELLED')]),
258
- 'WORKER_ID'
259
- );
260
-
261
- const getActionListenerSpy = jest
262
- .spyOn(worker.client.dispatcher, 'get_action_listener')
263
- .mockResolvedValue(mockActionListner);
264
-
265
- await worker.start();
266
-
267
- expect(getActionListenerSpy).toHaveBeenCalledTimes(1);
268
- expect(startSpy).toHaveBeenCalledTimes(1);
269
- expect(cancelSpy).toHaveBeenCalledTimes(1);
270
- });
271
-
272
- it('should retry 5 times to start a worker then throw an error', async () => {
273
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
274
-
275
- const startSpy = jest.spyOn(worker, 'handle_start_step_run').mockReturnValue();
276
- const cancelSpy = jest.spyOn(worker, 'handle_cancel_step_run').mockReturnValue();
277
-
278
- const mockActionListner = new ActionListener(
279
- hatchet.dispatcher,
280
- mockListener([mockStart, mockCancel, new ServerError(Status.CANCELLED, 'CANCELLED')]),
281
- 'WORKER_ID'
282
- );
283
-
284
- const getActionListenerSpy = jest
285
- .spyOn(worker.client.dispatcher, 'get_action_listener')
286
- .mockImplementationOnce(() => {
287
- throw new Error('Simulated error');
288
- })
289
- .mockImplementationOnce(() => {
290
- throw new Error('Simulated error');
291
- })
292
- .mockImplementationOnce(() => {
293
- throw new Error('Simulated error');
294
- })
295
- .mockImplementationOnce(() => {
296
- throw new Error('Simulated error');
297
- })
298
- .mockImplementationOnce(() => {
299
- throw new Error('Simulated error');
300
- })
301
- .mockImplementationOnce(() => {
302
- throw new Error('Simulated error');
303
- });
304
-
305
- await worker.start();
306
-
307
- expect(getActionListenerSpy).toHaveBeenCalledTimes(5);
308
- expect(startSpy).toHaveBeenCalledTimes(0);
309
- expect(cancelSpy).toHaveBeenCalledTimes(0);
310
- });
311
-
312
- it('should successfully run after retrying < 5 times', async () => {
313
- const worker = new Worker(hatchet, { name: 'WORKER_NAME' });
314
-
315
- const startSpy = jest.spyOn(worker, 'handle_start_step_run').mockReturnValue();
316
- const cancelSpy = jest.spyOn(worker, 'handle_cancel_step_run').mockReturnValue();
317
-
318
- const mockActionLister = new ActionListener(
319
- hatchet.dispatcher,
320
- mockListener([mockStart, mockCancel, new ServerError(Status.CANCELLED, 'CANCELLED')]),
321
- 'WORKER_ID'
322
- );
323
-
324
- const getActionListenerSpy = jest
325
- .spyOn(worker.client.dispatcher, 'get_action_listener')
326
- .mockImplementationOnce(() => {
327
- throw new Error('Simulated error');
328
- })
329
- .mockImplementationOnce(() => {
330
- throw new Error('Simulated error');
331
- })
332
- .mockImplementationOnce(() => {
333
- throw new Error('Simulated error');
334
- })
335
- .mockImplementationOnce(() => {
336
- throw new Error('Simulated error');
337
- })
338
- .mockImplementationOnce(async () => mockActionLister);
339
-
340
- await worker.start();
341
-
342
- expect(getActionListenerSpy).toHaveBeenCalledTimes(5);
343
- expect(startSpy).toHaveBeenCalledTimes(1);
344
- expect(cancelSpy).toHaveBeenCalledTimes(1);
345
- });
346
- });
347
- });