@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.
- package/clients/hatchet-client/client-config.d.ts +18 -0
- package/clients/hatchet-client/client-config.js +5 -0
- package/clients/rest/generated/Api.d.ts +88 -6
- package/clients/rest/generated/Api.js +51 -1
- package/clients/rest/generated/data-contracts.d.ts +57 -2
- package/clients/rest/generated/data-contracts.js +10 -1
- package/package.json +4 -2
- package/protoc/dispatcher/dispatcher.d.ts +1 -1
- package/protoc/dispatcher/dispatcher.js +29 -29
- package/protoc/events/events.d.ts +2 -2
- package/protoc/events/events.js +10 -10
- package/protoc/google/protobuf/timestamp.js +2 -2
- package/protoc/v1/dispatcher.d.ts +1 -1
- package/protoc/v1/dispatcher.js +5 -5
- package/protoc/v1/shared/condition.js +7 -7
- package/protoc/v1/workflows.d.ts +1 -1
- package/protoc/v1/workflows.js +16 -16
- package/protoc/workflows/workflows.d.ts +1 -1
- package/protoc/workflows/workflows.js +21 -21
- package/util/config-loader/config-loader.js +13 -8
- package/v1/client/worker/health-server.d.ts +30 -0
- package/v1/client/worker/health-server.js +161 -0
- package/v1/client/worker/worker-internal.d.ts +11 -0
- package/v1/client/worker/worker-internal.js +64 -2
- package/version.d.ts +1 -1
- package/version.js +1 -1
|
@@ -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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
(
|
|
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
|
-
(
|
|
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
|
-
(
|
|
76
|
-
apiUrl = (
|
|
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 = (
|
|
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: (
|
|
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
|
-
|
|
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)
|
|
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.
|
|
1
|
+
export declare const HATCHET_VERSION = "1.10.1";
|
package/version.js
CHANGED