@hatchet-dev/typescript-sdk 1.9.8 → 1.10.1

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.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Code generated by protoc-gen-ts_proto. DO NOT EDIT.
3
3
  // versions:
4
- // protoc-gen-ts_proto v2.7.0
4
+ // protoc-gen-ts_proto v2.7.7
5
5
  // protoc v3.19.1
6
6
  // source: workflows/workflows.proto
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -267,7 +267,7 @@ exports.PutWorkflowRequest = {
267
267
  },
268
268
  decode(input, length) {
269
269
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
270
- let end = length === undefined ? reader.len : reader.pos + length;
270
+ const end = length === undefined ? reader.len : reader.pos + length;
271
271
  const message = createBasePutWorkflowRequest();
272
272
  while (reader.pos < end) {
273
273
  const tag = reader.uint32();
@@ -377,7 +377,7 @@ exports.CreateWorkflowVersionOpts = {
377
377
  },
378
378
  decode(input, length) {
379
379
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
380
- let end = length === undefined ? reader.len : reader.pos + length;
380
+ const end = length === undefined ? reader.len : reader.pos + length;
381
381
  const message = createBaseCreateWorkflowVersionOpts();
382
382
  while (reader.pos < end) {
383
383
  const tag = reader.uint32();
@@ -619,7 +619,7 @@ exports.WorkflowConcurrencyOpts = {
619
619
  },
620
620
  decode(input, length) {
621
621
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
622
- let end = length === undefined ? reader.len : reader.pos + length;
622
+ const end = length === undefined ? reader.len : reader.pos + length;
623
623
  const message = createBaseWorkflowConcurrencyOpts();
624
624
  while (reader.pos < end) {
625
625
  const tag = reader.uint32();
@@ -717,7 +717,7 @@ exports.CreateWorkflowJobOpts = {
717
717
  },
718
718
  decode(input, length) {
719
719
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
720
- let end = length === undefined ? reader.len : reader.pos + length;
720
+ const end = length === undefined ? reader.len : reader.pos + length;
721
721
  const message = createBaseCreateWorkflowJobOpts();
722
722
  while (reader.pos < end) {
723
723
  const tag = reader.uint32();
@@ -816,7 +816,7 @@ exports.DesiredWorkerLabels = {
816
816
  },
817
817
  decode(input, length) {
818
818
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
819
- let end = length === undefined ? reader.len : reader.pos + length;
819
+ const end = length === undefined ? reader.len : reader.pos + length;
820
820
  const message = createBaseDesiredWorkerLabels();
821
821
  while (reader.pos < end) {
822
822
  const tag = reader.uint32();
@@ -962,7 +962,7 @@ exports.CreateWorkflowStepOpts = {
962
962
  },
963
963
  decode(input, length) {
964
964
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
965
- let end = length === undefined ? reader.len : reader.pos + length;
965
+ const end = length === undefined ? reader.len : reader.pos + length;
966
966
  const message = createBaseCreateWorkflowStepOpts();
967
967
  while (reader.pos < end) {
968
968
  const tag = reader.uint32();
@@ -1167,7 +1167,7 @@ exports.CreateWorkflowStepOpts_WorkerLabelsEntry = {
1167
1167
  },
1168
1168
  decode(input, length) {
1169
1169
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1170
- let end = length === undefined ? reader.len : reader.pos + length;
1170
+ const end = length === undefined ? reader.len : reader.pos + length;
1171
1171
  const message = createBaseCreateWorkflowStepOpts_WorkerLabelsEntry();
1172
1172
  while (reader.pos < end) {
1173
1173
  const tag = reader.uint32();
@@ -1258,7 +1258,7 @@ exports.CreateStepRateLimit = {
1258
1258
  },
1259
1259
  decode(input, length) {
1260
1260
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1261
- let end = length === undefined ? reader.len : reader.pos + length;
1261
+ const end = length === undefined ? reader.len : reader.pos + length;
1262
1262
  const message = createBaseCreateStepRateLimit();
1263
1263
  while (reader.pos < end) {
1264
1264
  const tag = reader.uint32();
@@ -1371,7 +1371,7 @@ exports.ListWorkflowsRequest = {
1371
1371
  },
1372
1372
  decode(input, length) {
1373
1373
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1374
- let end = length === undefined ? reader.len : reader.pos + length;
1374
+ const end = length === undefined ? reader.len : reader.pos + length;
1375
1375
  const message = createBaseListWorkflowsRequest();
1376
1376
  while (reader.pos < end) {
1377
1377
  const tag = reader.uint32();
@@ -1445,7 +1445,7 @@ exports.ScheduleWorkflowRequest = {
1445
1445
  },
1446
1446
  decode(input, length) {
1447
1447
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1448
- let end = length === undefined ? reader.len : reader.pos + length;
1448
+ const end = length === undefined ? reader.len : reader.pos + length;
1449
1449
  const message = createBaseScheduleWorkflowRequest();
1450
1450
  while (reader.pos < end) {
1451
1451
  const tag = reader.uint32();
@@ -1605,7 +1605,7 @@ exports.ScheduledWorkflow = {
1605
1605
  },
1606
1606
  decode(input, length) {
1607
1607
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1608
- let end = length === undefined ? reader.len : reader.pos + length;
1608
+ const end = length === undefined ? reader.len : reader.pos + length;
1609
1609
  const message = createBaseScheduledWorkflow();
1610
1610
  while (reader.pos < end) {
1611
1611
  const tag = reader.uint32();
@@ -1697,7 +1697,7 @@ exports.WorkflowVersion = {
1697
1697
  },
1698
1698
  decode(input, length) {
1699
1699
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1700
- let end = length === undefined ? reader.len : reader.pos + length;
1700
+ const end = length === undefined ? reader.len : reader.pos + length;
1701
1701
  const message = createBaseWorkflowVersion();
1702
1702
  while (reader.pos < end) {
1703
1703
  const tag = reader.uint32();
@@ -1830,7 +1830,7 @@ exports.WorkflowTriggerEventRef = {
1830
1830
  },
1831
1831
  decode(input, length) {
1832
1832
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1833
- let end = length === undefined ? reader.len : reader.pos + length;
1833
+ const end = length === undefined ? reader.len : reader.pos + length;
1834
1834
  const message = createBaseWorkflowTriggerEventRef();
1835
1835
  while (reader.pos < end) {
1836
1836
  const tag = reader.uint32();
@@ -1899,7 +1899,7 @@ exports.WorkflowTriggerCronRef = {
1899
1899
  },
1900
1900
  decode(input, length) {
1901
1901
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1902
- let end = length === undefined ? reader.len : reader.pos + length;
1902
+ const end = length === undefined ? reader.len : reader.pos + length;
1903
1903
  const message = createBaseWorkflowTriggerCronRef();
1904
1904
  while (reader.pos < end) {
1905
1905
  const tag = reader.uint32();
@@ -1965,7 +1965,7 @@ exports.BulkTriggerWorkflowRequest = {
1965
1965
  },
1966
1966
  decode(input, length) {
1967
1967
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
1968
- let end = length === undefined ? reader.len : reader.pos + length;
1968
+ const end = length === undefined ? reader.len : reader.pos + length;
1969
1969
  const message = createBaseBulkTriggerWorkflowRequest();
1970
1970
  while (reader.pos < end) {
1971
1971
  const tag = reader.uint32();
@@ -2022,7 +2022,7 @@ exports.BulkTriggerWorkflowResponse = {
2022
2022
  },
2023
2023
  decode(input, length) {
2024
2024
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
2025
- let end = length === undefined ? reader.len : reader.pos + length;
2025
+ const end = length === undefined ? reader.len : reader.pos + length;
2026
2026
  const message = createBaseBulkTriggerWorkflowResponse();
2027
2027
  while (reader.pos < end) {
2028
2028
  const tag = reader.uint32();
@@ -2113,7 +2113,7 @@ exports.TriggerWorkflowRequest = {
2113
2113
  },
2114
2114
  decode(input, length) {
2115
2115
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
2116
- let end = length === undefined ? reader.len : reader.pos + length;
2116
+ const end = length === undefined ? reader.len : reader.pos + length;
2117
2117
  const message = createBaseTriggerWorkflowRequest();
2118
2118
  while (reader.pos < end) {
2119
2119
  const tag = reader.uint32();
@@ -2269,7 +2269,7 @@ exports.TriggerWorkflowResponse = {
2269
2269
  },
2270
2270
  decode(input, length) {
2271
2271
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
2272
- let end = length === undefined ? reader.len : reader.pos + length;
2272
+ const end = length === undefined ? reader.len : reader.pos + length;
2273
2273
  const message = createBaseTriggerWorkflowResponse();
2274
2274
  while (reader.pos < end) {
2275
2275
  const tag = reader.uint32();
@@ -2329,7 +2329,7 @@ exports.PutRateLimitRequest = {
2329
2329
  },
2330
2330
  decode(input, length) {
2331
2331
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
2332
- let end = length === undefined ? reader.len : reader.pos + length;
2332
+ const end = length === undefined ? reader.len : reader.pos + length;
2333
2333
  const message = createBasePutRateLimitRequest();
2334
2334
  while (reader.pos < end) {
2335
2335
  const tag = reader.uint32();
@@ -2404,7 +2404,7 @@ exports.PutRateLimitResponse = {
2404
2404
  },
2405
2405
  decode(input, length) {
2406
2406
  const reader = input instanceof wire_1.BinaryReader ? input : new wire_1.BinaryReader(input);
2407
- let end = length === undefined ? reader.len : reader.pos + length;
2407
+ const end = length === undefined ? reader.len : reader.pos + length;
2408
2408
  const message = createBasePutRateLimitResponse();
2409
2409
  while (reader.pos < end) {
2410
2410
  const tag = reader.uint32();
@@ -44,7 +44,7 @@ const token_1 = require("./token");
44
44
  const DEFAULT_CONFIG_FILE = '.hatchet.yaml';
45
45
  class ConfigLoader {
46
46
  static loadClientConfig(override, config) {
47
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
47
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
48
48
  const yaml = this.loadYamlConfig(config === null || config === void 0 ? void 0 : config.path);
49
49
  const tlsConfig = (_a = override === null || override === void 0 ? void 0 : override.tls_config) !== null && _a !== void 0 ? _a : {
50
50
  tls_strategy: (_d = (_c = (_b = yaml === null || yaml === void 0 ? void 0 : yaml.tls_config) === null || _b === void 0 ? void 0 : _b.tls_strategy) !== null && _c !== void 0 ? _c : this.env('HATCHET_CLIENT_TLS_STRATEGY')) !== null && _d !== void 0 ? _d : 'tls',
@@ -54,6 +54,10 @@ class ConfigLoader {
54
54
  server_name: (_m = (_l = yaml === null || yaml === void 0 ? void 0 : yaml.tls_config) === null || _l === void 0 ? void 0 : _l.server_name) !== null && _m !== void 0 ? _m : this.env('HATCHET_CLIENT_TLS_SERVER_NAME'),
55
55
  };
56
56
  const token = (_p = (_o = override === null || override === void 0 ? void 0 : override.token) !== null && _o !== void 0 ? _o : yaml === null || yaml === void 0 ? void 0 : yaml.token) !== null && _p !== void 0 ? _p : this.env('HATCHET_CLIENT_TOKEN');
57
+ const healthCheckConfig = (_r = (_q = override === null || override === void 0 ? void 0 : override.healthcheck) !== null && _q !== void 0 ? _q : yaml === null || yaml === void 0 ? void 0 : yaml.healthcheck) !== null && _r !== void 0 ? _r : {
58
+ enabled: this.env('HATCHET_CLIENT_WORKER_HEALTHCHECK_ENABLED') === 'true',
59
+ port: parseInt(this.env('HATCHET_CLIENT_WORKER_HEALTHCHECK_PORT') || '8001', 10),
60
+ };
57
61
  if (!token) {
58
62
  throw new Error('No token provided. Provide it by setting the HATCHET_CLIENT_TOKEN environment variable.');
59
63
  }
@@ -66,25 +70,26 @@ class ConfigLoader {
66
70
  try {
67
71
  const addresses = (0, token_1.getAddressesFromJWT)(token);
68
72
  grpcBroadcastAddress =
69
- (_s = (_r = (_q = override === null || override === void 0 ? void 0 : override.host_port) !== null && _q !== void 0 ? _q : yaml === null || yaml === void 0 ? void 0 : yaml.host_port) !== null && _r !== void 0 ? _r : this.env('HATCHET_CLIENT_HOST_PORT')) !== null && _s !== void 0 ? _s : addresses.grpcBroadcastAddress;
73
+ (_u = (_t = (_s = override === null || override === void 0 ? void 0 : override.host_port) !== null && _s !== void 0 ? _s : yaml === null || yaml === void 0 ? void 0 : yaml.host_port) !== null && _t !== void 0 ? _t : this.env('HATCHET_CLIENT_HOST_PORT')) !== null && _u !== void 0 ? _u : addresses.grpcBroadcastAddress;
70
74
  apiUrl =
71
- (_v = (_u = (_t = override === null || override === void 0 ? void 0 : override.api_url) !== null && _t !== void 0 ? _t : yaml === null || yaml === void 0 ? void 0 : yaml.api_url) !== null && _u !== void 0 ? _u : this.env('HATCHET_CLIENT_API_URL')) !== null && _v !== void 0 ? _v : addresses.serverUrl;
75
+ (_x = (_w = (_v = override === null || override === void 0 ? void 0 : override.api_url) !== null && _v !== void 0 ? _v : yaml === null || yaml === void 0 ? void 0 : yaml.api_url) !== null && _w !== void 0 ? _w : this.env('HATCHET_CLIENT_API_URL')) !== null && _x !== void 0 ? _x : addresses.serverUrl;
72
76
  }
73
77
  catch (e) {
74
78
  grpcBroadcastAddress =
75
- (_x = (_w = override === null || override === void 0 ? void 0 : override.host_port) !== null && _w !== void 0 ? _w : yaml === null || yaml === void 0 ? void 0 : yaml.host_port) !== null && _x !== void 0 ? _x : this.env('HATCHET_CLIENT_HOST_PORT');
76
- apiUrl = (_z = (_y = override === null || override === void 0 ? void 0 : override.api_url) !== null && _y !== void 0 ? _y : yaml === null || yaml === void 0 ? void 0 : yaml.api_url) !== null && _z !== void 0 ? _z : this.env('HATCHET_CLIENT_API_URL');
79
+ (_z = (_y = override === null || override === void 0 ? void 0 : override.host_port) !== null && _y !== void 0 ? _y : yaml === null || yaml === void 0 ? void 0 : yaml.host_port) !== null && _z !== void 0 ? _z : this.env('HATCHET_CLIENT_HOST_PORT');
80
+ apiUrl = (_1 = (_0 = override === null || override === void 0 ? void 0 : override.api_url) !== null && _0 !== void 0 ? _0 : yaml === null || yaml === void 0 ? void 0 : yaml.api_url) !== null && _1 !== void 0 ? _1 : this.env('HATCHET_CLIENT_API_URL');
77
81
  }
78
- let namespace = (_1 = (_0 = override === null || override === void 0 ? void 0 : override.namespace) !== null && _0 !== void 0 ? _0 : yaml === null || yaml === void 0 ? void 0 : yaml.namespace) !== null && _1 !== void 0 ? _1 : this.env('HATCHET_CLIENT_NAMESPACE');
82
+ let namespace = (_3 = (_2 = override === null || override === void 0 ? void 0 : override.namespace) !== null && _2 !== void 0 ? _2 : yaml === null || yaml === void 0 ? void 0 : yaml.namespace) !== null && _3 !== void 0 ? _3 : this.env('HATCHET_CLIENT_NAMESPACE');
79
83
  if (namespace && !(namespace === null || namespace === void 0 ? void 0 : namespace.endsWith('_'))) {
80
84
  namespace = `${namespace}_`;
81
85
  }
82
86
  return {
83
- token: (_3 = (_2 = override === null || override === void 0 ? void 0 : override.token) !== null && _2 !== void 0 ? _2 : yaml === null || yaml === void 0 ? void 0 : yaml.token) !== null && _3 !== void 0 ? _3 : this.env('HATCHET_CLIENT_TOKEN'),
87
+ token: (_5 = (_4 = override === null || override === void 0 ? void 0 : override.token) !== null && _4 !== void 0 ? _4 : yaml === null || yaml === void 0 ? void 0 : yaml.token) !== null && _5 !== void 0 ? _5 : this.env('HATCHET_CLIENT_TOKEN'),
84
88
  host_port: grpcBroadcastAddress,
85
89
  api_url: apiUrl,
86
90
  tls_config: tlsConfig,
87
- log_level: (_6 = (_5 = (_4 = override === null || override === void 0 ? void 0 : override.log_level) !== null && _4 !== void 0 ? _4 : yaml === null || yaml === void 0 ? void 0 : yaml.log_level) !== null && _5 !== void 0 ? _5 : this.env('HATCHET_CLIENT_LOG_LEVEL')) !== null && _6 !== void 0 ? _6 : 'INFO',
91
+ healthcheck: healthCheckConfig,
92
+ log_level: (_8 = (_7 = (_6 = override === null || override === void 0 ? void 0 : override.log_level) !== null && _6 !== void 0 ? _6 : yaml === null || yaml === void 0 ? void 0 : yaml.log_level) !== null && _7 !== void 0 ? _7 : this.env('HATCHET_CLIENT_LOG_LEVEL')) !== null && _8 !== void 0 ? _8 : 'INFO',
88
93
  tenant_id: tenantId,
89
94
  namespace: namespace ? `${namespace}`.toLowerCase() : '',
90
95
  };
@@ -0,0 +1,30 @@
1
+ import { Logger } from '../../../util/logger';
2
+ export declare const workerStatus: {
3
+ readonly INITIALIZED: "INITIALIZED";
4
+ readonly STARTING: "STARTING";
5
+ readonly HEALTHY: "HEALTHY";
6
+ readonly UNHEALTHY: "UNHEALTHY";
7
+ };
8
+ export type WorkerStatus = (typeof workerStatus)[keyof typeof workerStatus];
9
+ export declare class HealthServer {
10
+ private port;
11
+ private getStatus;
12
+ private workerName;
13
+ private getSlots;
14
+ private getActions;
15
+ private getLabels;
16
+ private logger;
17
+ private server;
18
+ private register;
19
+ private workerStatusGauge;
20
+ private workerSlotsGauge;
21
+ private workerActionsGauge;
22
+ private metricsInitialized;
23
+ constructor(port: number, getStatus: () => WorkerStatus, workerName: string, getSlots: () => number, getActions: () => string[], getLabels: () => Record<string, string | number>, logger: Logger);
24
+ private handleRequest;
25
+ private handleHealth;
26
+ private initializeMetrics;
27
+ private handleMetrics;
28
+ start(): Promise<void>;
29
+ stop(): Promise<void>;
30
+ }
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.HealthServer = exports.workerStatus = void 0;
13
+ const node_http_1 = require("node:http");
14
+ exports.workerStatus = {
15
+ INITIALIZED: 'INITIALIZED',
16
+ STARTING: 'STARTING',
17
+ HEALTHY: 'HEALTHY',
18
+ UNHEALTHY: 'UNHEALTHY',
19
+ };
20
+ class HealthServer {
21
+ constructor(port, getStatus, workerName, getSlots, getActions, getLabels, logger) {
22
+ this.port = port;
23
+ this.getStatus = getStatus;
24
+ this.workerName = workerName;
25
+ this.getSlots = getSlots;
26
+ this.getActions = getActions;
27
+ this.getLabels = getLabels;
28
+ this.logger = logger;
29
+ this.server = null;
30
+ this.register = null;
31
+ this.workerStatusGauge = null;
32
+ this.workerSlotsGauge = null;
33
+ this.workerActionsGauge = null;
34
+ this.metricsInitialized = false;
35
+ this.initializeMetrics();
36
+ }
37
+ handleRequest(req, res) {
38
+ return __awaiter(this, void 0, void 0, function* () {
39
+ const url = req.url || '';
40
+ if (url === '/health' && req.method === 'GET') {
41
+ yield this.handleHealth(res);
42
+ }
43
+ else if (url === '/metrics' && req.method === 'GET') {
44
+ yield this.handleMetrics(res);
45
+ }
46
+ else {
47
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
48
+ res.end('Not Found');
49
+ }
50
+ });
51
+ }
52
+ handleHealth(res) {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ const response = {
55
+ status: this.getStatus(),
56
+ name: this.workerName,
57
+ slots: this.getSlots(),
58
+ actions: this.getActions(),
59
+ labels: this.getLabels(),
60
+ nodeVersion: process.version,
61
+ };
62
+ res.writeHead(200, { 'Content-Type': 'application/json' });
63
+ yield res.end(JSON.stringify(response));
64
+ });
65
+ }
66
+ initializeMetrics() {
67
+ try {
68
+ // @ts-ignore - prom-client is an optional dependency
69
+ // eslint-disable-next-line
70
+ const { Registry, Gauge, collectDefaultMetrics } = require('prom-client');
71
+ this.register = new Registry();
72
+ collectDefaultMetrics({ register: this.register });
73
+ this.workerStatusGauge = new Gauge({
74
+ name: 'hatchet_worker_status',
75
+ help: 'Current status of the Hatchet worker',
76
+ registers: [this.register],
77
+ collect: () => {
78
+ this.workerStatusGauge.set(this.getStatus() === exports.workerStatus.HEALTHY ? 1 : 0);
79
+ },
80
+ });
81
+ this.workerSlotsGauge = new Gauge({
82
+ name: 'hatchet_worker_slots',
83
+ help: 'Total slots available on the worker',
84
+ registers: [this.register],
85
+ collect: () => {
86
+ this.workerSlotsGauge.set(this.getSlots());
87
+ },
88
+ });
89
+ this.workerActionsGauge = new Gauge({
90
+ name: 'hatchet_worker_actions',
91
+ help: 'Number of registered actions on the worker',
92
+ registers: [this.register],
93
+ collect: () => {
94
+ this.workerActionsGauge.set(this.getActions().length);
95
+ },
96
+ });
97
+ this.metricsInitialized = true;
98
+ }
99
+ catch (error) {
100
+ this.metricsInitialized = false;
101
+ this.logger.error('Metrics initialization failed - prom-client dependency not installed');
102
+ }
103
+ }
104
+ handleMetrics(res) {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ if (!this.metricsInitialized || !this.register) {
107
+ this.logger.error('Metrics initialization failed - prom-client dependency not installed');
108
+ res.writeHead(503, { 'Content-Type': 'text/plain' });
109
+ res.end('Metrics initialization failed');
110
+ return;
111
+ }
112
+ try {
113
+ const metrics = yield this.register.metrics();
114
+ res.writeHead(200, { 'Content-Type': this.register.contentType });
115
+ res.end(metrics);
116
+ }
117
+ catch (error) {
118
+ this.logger.error(`Error generating metrics: ${error}`);
119
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
120
+ res.end('Error generating metrics');
121
+ }
122
+ });
123
+ }
124
+ start() {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ return new Promise((resolve, reject) => {
127
+ try {
128
+ this.server = (0, node_http_1.createServer)((req, res) => {
129
+ this.handleRequest(req, res);
130
+ });
131
+ this.server.listen(this.port, '0.0.0.0', () => {
132
+ this.logger.info(`Health check server running on port ${this.port}`);
133
+ resolve();
134
+ });
135
+ this.server.on('error', (error) => {
136
+ this.logger.error(`Failed to start health check server: ${error.message}`);
137
+ reject(error);
138
+ });
139
+ }
140
+ catch (error) {
141
+ this.logger.error(`Failed to start health check server: ${error}`);
142
+ reject(error);
143
+ }
144
+ });
145
+ });
146
+ }
147
+ stop() {
148
+ return __awaiter(this, void 0, void 0, function* () {
149
+ if (this.server) {
150
+ return new Promise((resolve) => {
151
+ this.server.close(() => {
152
+ this.logger.info('Health check server stopped!');
153
+ resolve();
154
+ });
155
+ });
156
+ }
157
+ return Promise.resolve();
158
+ });
159
+ }
160
+ }
161
+ exports.HealthServer = HealthServer;
@@ -14,6 +14,8 @@ export interface WorkerOpts {
14
14
  handleKill?: boolean;
15
15
  maxRuns?: number;
16
16
  labels?: WorkerLabels;
17
+ healthPort?: number;
18
+ enableHealthServer?: boolean;
17
19
  }
18
20
  export declare class V1Worker {
19
21
  client: HatchetClient;
@@ -30,12 +32,21 @@ export declare class V1Worker {
30
32
  logger: Logger;
31
33
  registeredWorkflowPromises: Array<Promise<any>>;
32
34
  labels: WorkerLabels;
35
+ healthPort: number;
36
+ enableHealthServer: boolean;
37
+ private healthServer;
38
+ private status;
33
39
  constructor(client: HatchetClient, options: {
34
40
  name: string;
35
41
  handleKill?: boolean;
36
42
  maxRuns?: number;
37
43
  labels?: WorkerLabels;
38
44
  });
45
+ private initializeHealthServer;
46
+ private getAvailableSlots;
47
+ private getRegisteredActions;
48
+ private getFilteredLabels;
49
+ private setStatus;
39
50
  private registerActions;
40
51
  getHandler(workflows: Workflow[]): void;
41
52
  registerWebhook(webhook: WebhookWorkerCreateRequest): Promise<import("axios").AxiosResponse<import("../../../clients/rest/generated/data-contracts").WebhookWorkerCreated, any, {}>>;
@@ -32,23 +32,61 @@ const step_1 = require("../../../step");
32
32
  const apply_namespace_1 = require("../../../util/apply-namespace");
33
33
  const context_1 = require("./context");
34
34
  const parent_run_context_vars_1 = require("../../parent-run-context-vars");
35
+ const health_server_1 = require("./health-server");
35
36
  class V1Worker {
36
37
  constructor(client, options) {
38
+ var _a, _b, _c, _d;
37
39
  this.workflow_registry = [];
38
40
  this.futures = {};
39
41
  this.contexts = {};
40
42
  this.registeredWorkflowPromises = [];
41
43
  this.labels = {};
44
+ this.status = health_server_1.workerStatus.INITIALIZED;
42
45
  this.client = client;
43
46
  this.name = (0, apply_namespace_1.applyNamespace)(options.name, this.client.config.namespace);
44
47
  this.action_registry = {};
45
48
  this.maxRuns = options.maxRuns;
46
49
  this.labels = options.labels || {};
50
+ this.enableHealthServer = (_b = (_a = client.config.healthcheck) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : false;
51
+ this.healthPort = (_d = (_c = client.config.healthcheck) === null || _c === void 0 ? void 0 : _c.port) !== null && _d !== void 0 ? _d : 8001;
47
52
  process.on('SIGTERM', () => this.exitGracefully(true));
48
53
  process.on('SIGINT', () => this.exitGracefully(true));
49
54
  this.killing = false;
50
55
  this.handle_kill = options.handleKill === undefined ? true : options.handleKill;
51
56
  this.logger = client.config.logger(`Worker/${this.name}`, this.client.config.log_level);
57
+ if (this.enableHealthServer && this.healthPort) {
58
+ this.initializeHealthServer();
59
+ }
60
+ }
61
+ initializeHealthServer() {
62
+ if (!this.healthPort) {
63
+ this.logger.warn('Health server enabled but no port specified');
64
+ return;
65
+ }
66
+ this.healthServer = new health_server_1.HealthServer(this.healthPort, () => this.status, this.name, () => this.getAvailableSlots(), () => this.getRegisteredActions(), () => this.getFilteredLabels(), this.logger);
67
+ }
68
+ getAvailableSlots() {
69
+ if (!this.maxRuns) {
70
+ return 0;
71
+ }
72
+ const currentRuns = Object.keys(this.futures).length;
73
+ return Math.max(0, this.maxRuns - currentRuns);
74
+ }
75
+ getRegisteredActions() {
76
+ return Object.keys(this.action_registry);
77
+ }
78
+ getFilteredLabels() {
79
+ const filtered = {};
80
+ for (const [key, value] of Object.entries(this.labels)) {
81
+ if (value !== undefined) {
82
+ filtered[key] = value;
83
+ }
84
+ }
85
+ return filtered;
86
+ }
87
+ setStatus(status) {
88
+ this.status = status;
89
+ this.logger.debug(`Worker status changed to: ${status}`);
52
90
  }
53
91
  registerActions(workflow) {
54
92
  var _a;
@@ -195,8 +233,10 @@ class V1Worker {
195
233
  this.logger.warn(`\`on\` for event and cron triggers is deprecated and will be removed soon, use \`onEvents\` and \`onCrons\` instead for ${workflow.name}`);
196
234
  }
197
235
  const eventTriggers = [
198
- ...(workflow.onEvents || []),
199
- ...(((_u = workflow.on) === null || _u === void 0 ? void 0 : _u.event) ? [workflow.on.event] : []),
236
+ ...(workflow.onEvents || []).map((event) => (0, apply_namespace_1.applyNamespace)(event, this.client.config.namespace)),
237
+ ...(((_u = workflow.on) === null || _u === void 0 ? void 0 : _u.event)
238
+ ? [(0, apply_namespace_1.applyNamespace)(workflow.on.event, this.client.config.namespace)]
239
+ : []),
200
240
  ];
201
241
  const cronTriggers = [
202
242
  ...(workflow.onCrons || []),
@@ -582,6 +622,7 @@ class V1Worker {
582
622
  return __awaiter(this, void 0, void 0, function* () {
583
623
  var _a;
584
624
  this.killing = true;
625
+ this.setStatus(health_server_1.workerStatus.UNHEALTHY);
585
626
  this.logger.info('Starting to exit...');
586
627
  try {
587
628
  yield ((_a = this.listener) === null || _a === void 0 ? void 0 : _a.unregister());
@@ -593,6 +634,14 @@ class V1Worker {
593
634
  // attempt to wait for futures to finish
594
635
  yield Promise.all(Object.values(this.futures).map(({ promise }) => promise));
595
636
  this.logger.info('Successfully finished pending tasks.');
637
+ if (this.healthServer) {
638
+ try {
639
+ yield this.healthServer.stop();
640
+ }
641
+ catch (e) {
642
+ this.logger.error(`Could not stop health server: ${e.message}`);
643
+ }
644
+ }
596
645
  if (handleKill) {
597
646
  this.logger.info('Exiting hatchet worker...');
598
647
  process.exit(0);
@@ -602,6 +651,17 @@ class V1Worker {
602
651
  start() {
603
652
  return __awaiter(this, void 0, void 0, function* () {
604
653
  var _a, e_1, _b, _c;
654
+ this.setStatus(health_server_1.workerStatus.STARTING);
655
+ if (this.healthServer) {
656
+ try {
657
+ yield this.healthServer.start();
658
+ }
659
+ catch (e) {
660
+ this.logger.error(`Could not start health server: ${e.message}`);
661
+ this.setStatus(health_server_1.workerStatus.UNHEALTHY);
662
+ return;
663
+ }
664
+ }
605
665
  // ensure all workflows are registered
606
666
  yield Promise.all(this.registeredWorkflowPromises);
607
667
  if (Object.keys(this.action_registry).length === 0) {
@@ -616,6 +676,7 @@ class V1Worker {
616
676
  labels: this.labels,
617
677
  });
618
678
  this.workerId = this.listener.workerId;
679
+ this.setStatus(health_server_1.workerStatus.HEALTHY);
619
680
  const generator = this.listener.actions();
620
681
  this.logger.info(`Worker ${this.name} listening for actions`);
621
682
  try {
@@ -636,6 +697,7 @@ class V1Worker {
636
697
  }
637
698
  }
638
699
  catch (e) {
700
+ this.setStatus(health_server_1.workerStatus.UNHEALTHY);
639
701
  if (this.killing) {
640
702
  this.logger.info(`Exiting worker, ignoring error: ${e.message}`);
641
703
  return;
package/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const HATCHET_VERSION = "1.9.8";
1
+ export declare const HATCHET_VERSION = "1.10.1";
package/version.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.HATCHET_VERSION = void 0;
4
- exports.HATCHET_VERSION = '1.9.8';
4
+ exports.HATCHET_VERSION = '1.10.1';