@hatchet-dev/typescript-sdk 1.10.8 → 1.12.0
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/admin/admin-client.d.ts +38 -0
- package/clients/admin/admin-client.js +19 -6
- package/clients/dispatcher/action-listener.d.ts +6 -2
- package/clients/dispatcher/action-listener.js +2 -2
- package/clients/dispatcher/dispatcher-client.d.ts +8 -2
- package/clients/dispatcher/dispatcher-client.js +18 -4
- package/clients/event/event-client.d.ts +2 -2
- package/clients/event/event-client.js +4 -4
- package/clients/hatchet-client/hatchet-logger.js +2 -2
- package/clients/rest/generated/data-contracts.d.ts +13 -1
- package/clients/worker/worker.js +11 -11
- package/examples/webhooks.d.ts +1 -0
- package/examples/webhooks.js +45 -0
- package/package.json +1 -1
- package/protoc/dispatcher/dispatcher.d.ts +25 -25
- package/protoc/dispatcher/dispatcher.js +109 -95
- package/protoc/events/events.d.ts +4 -4
- package/protoc/events/events.js +20 -16
- package/protoc/v1/workflows.d.ts +7 -7
- package/protoc/workflows/workflows.d.ts +22 -22
- package/protoc/workflows/workflows.js +18 -18
- package/step.d.ts +1 -1
- package/step.js +19 -19
- package/util/workflow-run-ref.js +1 -1
- package/v1/client/admin.d.ts +30 -0
- package/v1/client/admin.js +21 -6
- package/v1/client/client.d.ts +8 -1
- package/v1/client/client.js +12 -1
- package/v1/client/features/metrics.d.ts +16 -5
- package/v1/client/features/metrics.js +13 -14
- package/v1/client/features/runs.d.ts +9 -1
- package/v1/client/features/runs.js +4 -2
- package/v1/client/features/webhooks.d.ts +28 -0
- package/v1/client/features/webhooks.js +97 -0
- package/v1/client/worker/context.d.ts +1 -1
- package/v1/client/worker/context.js +23 -23
- package/v1/client/worker/worker-internal.d.ts +2 -2
- package/v1/client/worker/worker-internal.js +25 -25
- package/v1/declaration.d.ts +2 -2
- package/v1/declaration.js +24 -10
- package/v1/parent-run-context-vars.d.ts +4 -1
- package/v1/parent-run-context-vars.js +1 -0
- package/version.d.ts +1 -1
- package/version.js +1 -1
package/v1/client/client.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { ScheduleClient } from './features/schedules';
|
|
|
20
20
|
import { CronClient } from './features/crons';
|
|
21
21
|
import { CELClient } from './features/cel';
|
|
22
22
|
import { TenantClient } from './features/tenant';
|
|
23
|
+
import { WebhooksClient } from './features/webhooks';
|
|
23
24
|
/**
|
|
24
25
|
* HatchetV1 implements the main client interface for interacting with the Hatchet workflow engine.
|
|
25
26
|
* It provides methods for creating and executing workflows, as well as managing workers.
|
|
@@ -193,6 +194,12 @@ export declare class HatchetClient implements IHatchetClient {
|
|
|
193
194
|
* @returns A tenant client instance
|
|
194
195
|
*/
|
|
195
196
|
get tenant(): TenantClient;
|
|
197
|
+
private _webhooks;
|
|
198
|
+
/**
|
|
199
|
+
* Get the webhooks client for creating and managing webhooks
|
|
200
|
+
* @returns A webhooks client instance
|
|
201
|
+
*/
|
|
202
|
+
get webhooks(): WebhooksClient;
|
|
196
203
|
private _ratelimits;
|
|
197
204
|
/**
|
|
198
205
|
* Get the rate limits client for creating and managing rate limits
|
|
@@ -245,6 +252,6 @@ export declare class HatchetClient implements IHatchetClient {
|
|
|
245
252
|
* @param workflows - The workflows to register on the webhooks
|
|
246
253
|
* @returns A promise that resolves when the webhook is registered
|
|
247
254
|
*/
|
|
248
|
-
|
|
255
|
+
v0webhooks(workflows: V0Workflow[]): import("../../clients/worker/handler").WebhookHandler;
|
|
249
256
|
runRef<T extends Record<string, any> = any>(id: string): WorkflowRunRef<T>;
|
|
250
257
|
}
|
package/v1/client/client.js
CHANGED
|
@@ -37,6 +37,7 @@ const schedules_1 = require("./features/schedules");
|
|
|
37
37
|
const crons_1 = require("./features/crons");
|
|
38
38
|
const cel_1 = require("./features/cel");
|
|
39
39
|
const tenant_1 = require("./features/tenant");
|
|
40
|
+
const webhooks_1 = require("./features/webhooks");
|
|
40
41
|
/**
|
|
41
42
|
* HatchetV1 implements the main client interface for interacting with the Hatchet workflow engine.
|
|
42
43
|
* It provides methods for creating and executing workflows, as well as managing workers.
|
|
@@ -289,6 +290,16 @@ class HatchetClient {
|
|
|
289
290
|
}
|
|
290
291
|
return this._tenant;
|
|
291
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Get the webhooks client for creating and managing webhooks
|
|
295
|
+
* @returns A webhooks client instance
|
|
296
|
+
*/
|
|
297
|
+
get webhooks() {
|
|
298
|
+
if (!this._webhooks) {
|
|
299
|
+
this._webhooks = new webhooks_1.WebhooksClient(this);
|
|
300
|
+
}
|
|
301
|
+
return this._webhooks;
|
|
302
|
+
}
|
|
292
303
|
/**
|
|
293
304
|
* Get the rate limits client for creating and managing rate limits
|
|
294
305
|
* @returns A rate limits client instance
|
|
@@ -374,7 +385,7 @@ class HatchetClient {
|
|
|
374
385
|
* @param workflows - The workflows to register on the webhooks
|
|
375
386
|
* @returns A promise that resolves when the webhook is registered
|
|
376
387
|
*/
|
|
377
|
-
|
|
388
|
+
v0webhooks(workflows) {
|
|
378
389
|
return this._v0.webhooks(workflows);
|
|
379
390
|
}
|
|
380
391
|
runRef(id) {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { BaseWorkflowDeclaration } from '../..';
|
|
2
|
-
import { Workflow } from '../../../workflow';
|
|
3
1
|
import { HatchetClient } from '../client';
|
|
2
|
+
export type TaskStatusMetrics = {
|
|
3
|
+
cancelled: number;
|
|
4
|
+
completed: number;
|
|
5
|
+
failed: number;
|
|
6
|
+
queued: number;
|
|
7
|
+
running: number;
|
|
8
|
+
};
|
|
4
9
|
/**
|
|
5
10
|
* MetricsClient is used to get metrics for workflows
|
|
6
11
|
*/
|
|
@@ -8,7 +13,13 @@ export declare class MetricsClient {
|
|
|
8
13
|
tenantId: string;
|
|
9
14
|
api: HatchetClient['api'];
|
|
10
15
|
constructor(client: HatchetClient);
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Get task/run status metrics for a tenant.
|
|
18
|
+
*
|
|
19
|
+
* This backs the dashboard "runs list" status count badges.
|
|
20
|
+
*
|
|
21
|
+
* Endpoint: GET /api/v1/stable/tenants/{tenant}/task-metrics
|
|
22
|
+
*/
|
|
23
|
+
getTaskStatusMetrics(query: Parameters<typeof this.api.v1TaskListStatusMetrics>[1], requestParams?: Parameters<typeof this.api.v1TaskListStatusMetrics>[2]): Promise<TaskStatusMetrics>;
|
|
24
|
+
getQueueMetrics(opts?: Parameters<typeof this.api.tenantGetStepRunQueueMetrics>[1]): Promise<import("../../../clients/rest/generated/data-contracts").TenantStepRunQueueMetrics>;
|
|
14
25
|
}
|
|
@@ -10,7 +10,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.MetricsClient = void 0;
|
|
13
|
-
const v1_1 = require("../..");
|
|
14
13
|
/**
|
|
15
14
|
* MetricsClient is used to get metrics for workflows
|
|
16
15
|
*/
|
|
@@ -19,24 +18,24 @@ class MetricsClient {
|
|
|
19
18
|
this.tenantId = client.tenantId;
|
|
20
19
|
this.api = client.api;
|
|
21
20
|
}
|
|
22
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Get task/run status metrics for a tenant.
|
|
23
|
+
*
|
|
24
|
+
* This backs the dashboard "runs list" status count badges.
|
|
25
|
+
*
|
|
26
|
+
* Endpoint: GET /api/v1/stable/tenants/{tenant}/task-metrics
|
|
27
|
+
*/
|
|
28
|
+
getTaskStatusMetrics(query, requestParams) {
|
|
23
29
|
return __awaiter(this, void 0, void 0, function* () {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
const { data } = yield this.api.v1TaskListStatusMetrics(this.tenantId, query, requestParams);
|
|
31
|
+
return data.reduce((acc, curr) => {
|
|
32
|
+
acc[curr.status.toLowerCase()] = curr.count;
|
|
33
|
+
return acc;
|
|
34
|
+
}, {});
|
|
27
35
|
});
|
|
28
36
|
}
|
|
29
37
|
getQueueMetrics(opts) {
|
|
30
38
|
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
-
// TODO IMPORTANT workflow id is the uuid for the workflow... not its name
|
|
32
|
-
// const stringWorkflows = opts?.workflows?
|
|
33
|
-
const { data } = yield this.api.tenantGetQueueMetrics(this.tenantId, Object.assign({}, opts));
|
|
34
|
-
return data;
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
getTaskMetrics(opts) {
|
|
38
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
// TODO what is this...
|
|
40
39
|
const { data } = yield this.api.tenantGetStepRunQueueMetrics(this.tenantId, opts);
|
|
41
40
|
return data;
|
|
42
41
|
});
|
|
@@ -40,12 +40,20 @@ export interface ListRunsOpts extends RunFilter {
|
|
|
40
40
|
/** Whether to include DAGs or only to include tasks */
|
|
41
41
|
onlyTasks: boolean;
|
|
42
42
|
/**
|
|
43
|
-
* The parent task external id to filter by
|
|
43
|
+
* The parent task run external id to filter by
|
|
44
|
+
* @deprecated use parentTaskRunExternalId instead
|
|
44
45
|
* @format uuid
|
|
45
46
|
* @minLength 36
|
|
46
47
|
* @maxLength 36
|
|
47
48
|
*/
|
|
48
49
|
parentTaskExternalId?: string;
|
|
50
|
+
/**
|
|
51
|
+
* The parent task run external id to filter by
|
|
52
|
+
* @format uuid
|
|
53
|
+
* @minLength 36
|
|
54
|
+
* @maxLength 36
|
|
55
|
+
*/
|
|
56
|
+
parentTaskRunExternalId?: string;
|
|
49
57
|
/**
|
|
50
58
|
* The triggering event external id to filter by
|
|
51
59
|
* @format uuid
|
|
@@ -62,7 +62,9 @@ class RunsClient {
|
|
|
62
62
|
}
|
|
63
63
|
list(opts) {
|
|
64
64
|
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
-
const
|
|
65
|
+
const normalizedOpts = (opts === null || opts === void 0 ? void 0 : opts.parentTaskExternalId) && !(opts === null || opts === void 0 ? void 0 : opts.parentTaskRunExternalId)
|
|
66
|
+
? Object.assign(Object.assign({}, opts), { parentTaskRunExternalId: opts.parentTaskExternalId }) : opts;
|
|
67
|
+
const { data } = yield this.api.v1WorkflowRunList(this.tenantId, Object.assign({}, (yield this.prepareListFilter(normalizedOpts || {}))));
|
|
66
68
|
return data;
|
|
67
69
|
});
|
|
68
70
|
}
|
|
@@ -114,7 +116,7 @@ class RunsClient {
|
|
|
114
116
|
workflow_ids: yield Promise.all(((_b = opts.workflowNames) === null || _b === void 0 ? void 0 : _b.map((name) => __awaiter(this, void 0, void 0, function* () { return (yield this.workflows.get(name)).metadata.id; }))) || []),
|
|
115
117
|
additional_metadata: am,
|
|
116
118
|
only_tasks: opts.onlyTasks || false,
|
|
117
|
-
parent_task_external_id: opts.
|
|
119
|
+
parent_task_external_id: opts.parentTaskRunExternalId,
|
|
118
120
|
triggering_event_external_id: opts.triggeringEventExternalId,
|
|
119
121
|
include_payloads: opts.includePayloads,
|
|
120
122
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { V1CreateWebhookRequestBase, V1UpdateWebhookRequest, V1Webhook, V1WebhookList, V1WebhookSourceName, V1WebhookAPIKeyAuth, V1WebhookBasicAuth, V1WebhookHMACAuth } from '../../../clients/rest/generated/data-contracts';
|
|
2
|
+
import { HatchetClient } from '../client';
|
|
3
|
+
export type CreateWebhookOptions = V1CreateWebhookRequestBase & {
|
|
4
|
+
auth: V1WebhookBasicAuth | V1WebhookAPIKeyAuth | V1WebhookHMACAuth;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Client for managing incoming webhooks in Hatchet.
|
|
8
|
+
*
|
|
9
|
+
* Webhooks allow external systems to trigger Hatchet workflows by sending HTTP
|
|
10
|
+
* requests to dedicated endpoints. This enables real-time integration with
|
|
11
|
+
* third-party services like GitHub, Stripe, Slack, or any system that can send
|
|
12
|
+
* webhook events.
|
|
13
|
+
*/
|
|
14
|
+
export declare class WebhooksClient {
|
|
15
|
+
api: HatchetClient['api'];
|
|
16
|
+
tenantId: string;
|
|
17
|
+
constructor(client: HatchetClient);
|
|
18
|
+
list(options?: {
|
|
19
|
+
limit?: number;
|
|
20
|
+
offset?: number;
|
|
21
|
+
webhookNames?: string[];
|
|
22
|
+
sourceNames?: V1WebhookSourceName[];
|
|
23
|
+
}): Promise<V1WebhookList>;
|
|
24
|
+
get(webhookName: string): Promise<V1Webhook>;
|
|
25
|
+
create(request: CreateWebhookOptions): Promise<V1Webhook>;
|
|
26
|
+
update(webhookName: string, options?: Partial<V1UpdateWebhookRequest>): Promise<V1Webhook>;
|
|
27
|
+
delete(webhookName: string): Promise<V1Webhook>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.WebhooksClient = void 0;
|
|
24
|
+
const data_contracts_1 = require("../../../clients/rest/generated/data-contracts");
|
|
25
|
+
function getAuthType(auth) {
|
|
26
|
+
if ('username' in auth && 'password' in auth)
|
|
27
|
+
return data_contracts_1.V1WebhookAuthType.BASIC;
|
|
28
|
+
if ('headerName' in auth && 'apiKey' in auth)
|
|
29
|
+
return data_contracts_1.V1WebhookAuthType.API_KEY;
|
|
30
|
+
if ('signingSecret' in auth &&
|
|
31
|
+
'signatureHeaderName' in auth &&
|
|
32
|
+
'algorithm' in auth &&
|
|
33
|
+
'encoding' in auth) {
|
|
34
|
+
return data_contracts_1.V1WebhookAuthType.HMAC;
|
|
35
|
+
}
|
|
36
|
+
throw new Error('Invalid webhook auth');
|
|
37
|
+
}
|
|
38
|
+
function toCreateWebhookRequest(options) {
|
|
39
|
+
const { auth } = options, base = __rest(options, ["auth"]);
|
|
40
|
+
const authType = getAuthType(auth);
|
|
41
|
+
return Object.assign(Object.assign({}, base), { authType, auth });
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Client for managing incoming webhooks in Hatchet.
|
|
45
|
+
*
|
|
46
|
+
* Webhooks allow external systems to trigger Hatchet workflows by sending HTTP
|
|
47
|
+
* requests to dedicated endpoints. This enables real-time integration with
|
|
48
|
+
* third-party services like GitHub, Stripe, Slack, or any system that can send
|
|
49
|
+
* webhook events.
|
|
50
|
+
*/
|
|
51
|
+
class WebhooksClient {
|
|
52
|
+
constructor(client) {
|
|
53
|
+
this.api = client.api;
|
|
54
|
+
this.tenantId = client.tenantId;
|
|
55
|
+
}
|
|
56
|
+
list(options) {
|
|
57
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
+
const response = yield this.api.v1WebhookList(this.tenantId, {
|
|
59
|
+
limit: options === null || options === void 0 ? void 0 : options.limit,
|
|
60
|
+
offset: options === null || options === void 0 ? void 0 : options.offset,
|
|
61
|
+
webhookNames: options === null || options === void 0 ? void 0 : options.webhookNames,
|
|
62
|
+
sourceNames: options === null || options === void 0 ? void 0 : options.sourceNames,
|
|
63
|
+
});
|
|
64
|
+
return response.data;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
get(webhookName) {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
const response = yield this.api.v1WebhookGet(this.tenantId, webhookName);
|
|
70
|
+
return response.data;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
create(request) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
const payload = toCreateWebhookRequest(request);
|
|
76
|
+
const response = yield this.api.v1WebhookCreate(this.tenantId, payload);
|
|
77
|
+
return response.data;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
update(webhookName_1) {
|
|
81
|
+
return __awaiter(this, arguments, void 0, function* (webhookName, options = {}) {
|
|
82
|
+
const response = yield this.api.v1WebhookUpdate(this.tenantId, webhookName, {
|
|
83
|
+
eventKeyExpression: options.eventKeyExpression,
|
|
84
|
+
scopeExpression: options.scopeExpression,
|
|
85
|
+
staticPayload: options.staticPayload,
|
|
86
|
+
});
|
|
87
|
+
return response.data;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
delete(webhookName) {
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
const response = yield this.api.v1WebhookDelete(this.tenantId, webhookName);
|
|
93
|
+
return response.data;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.WebhooksClient = WebhooksClient;
|
|
@@ -112,7 +112,7 @@ export declare class Context<T, K = {}> {
|
|
|
112
112
|
* Gets the ID of the current task run.
|
|
113
113
|
* @returns The task run ID.
|
|
114
114
|
*/
|
|
115
|
-
|
|
115
|
+
taskRunExternalId(): string;
|
|
116
116
|
/**
|
|
117
117
|
* Gets the number of times the current task has been retried.
|
|
118
118
|
* @returns The retry count.
|
|
@@ -59,7 +59,7 @@ class Context {
|
|
|
59
59
|
cancel() {
|
|
60
60
|
return __awaiter(this, void 0, void 0, function* () {
|
|
61
61
|
yield this.v1.runs.cancel({
|
|
62
|
-
ids: [this.action.
|
|
62
|
+
ids: [this.action.taskRunExternalId],
|
|
63
63
|
});
|
|
64
64
|
// optimistically abort the run
|
|
65
65
|
this.controller.abort();
|
|
@@ -150,7 +150,7 @@ class Context {
|
|
|
150
150
|
* @returns The name of the task.
|
|
151
151
|
*/
|
|
152
152
|
taskName() {
|
|
153
|
-
return this.action.
|
|
153
|
+
return this.action.taskName;
|
|
154
154
|
}
|
|
155
155
|
/**
|
|
156
156
|
* Gets the ID of the current workflow run.
|
|
@@ -177,8 +177,8 @@ class Context {
|
|
|
177
177
|
* Gets the ID of the current task run.
|
|
178
178
|
* @returns The task run ID.
|
|
179
179
|
*/
|
|
180
|
-
|
|
181
|
-
return this.action.
|
|
180
|
+
taskRunExternalId() {
|
|
181
|
+
return this.action.taskRunExternalId;
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
184
184
|
* Gets the number of times the current task has been retried.
|
|
@@ -194,14 +194,14 @@ class Context {
|
|
|
194
194
|
* @deprecated use ctx.logger.infoger.info, ctx.logger.infoger.debug, ctx.logger.infoger.warn, ctx.logger.infoger.error, ctx.logger.infoger.trace instead
|
|
195
195
|
*/
|
|
196
196
|
log(message, level, extra) {
|
|
197
|
-
const {
|
|
198
|
-
if (!
|
|
197
|
+
const { taskRunExternalId } = this.action;
|
|
198
|
+
if (!taskRunExternalId) {
|
|
199
199
|
// log a warning
|
|
200
200
|
this._logger.warn('cannot log from context without stepRunId');
|
|
201
201
|
return Promise.resolve();
|
|
202
202
|
}
|
|
203
203
|
const logger = this.v1.config.logger('ctx', this.v1.config.log_level);
|
|
204
|
-
const contextExtra = Object.assign({ workflowRunId: this.action.workflowRunId,
|
|
204
|
+
const contextExtra = Object.assign({ workflowRunId: this.action.workflowRunId, taskRunExternalId: this.action.taskRunExternalId, retryCount: this.action.retryCount, workflowName: this.action.jobName }, extra === null || extra === void 0 ? void 0 : extra.extra);
|
|
205
205
|
const promises = [];
|
|
206
206
|
if (!level || level === 'INFO') {
|
|
207
207
|
promises.push(logger.info(message, contextExtra));
|
|
@@ -216,7 +216,7 @@ class Context {
|
|
|
216
216
|
promises.push(logger.error(message, extra === null || extra === void 0 ? void 0 : extra.error, contextExtra));
|
|
217
217
|
}
|
|
218
218
|
// FIXME: this is a hack to get around the fact that the log level is not typed
|
|
219
|
-
promises.push(this.v1.event.putLog(
|
|
219
|
+
promises.push(this.v1.event.putLog(taskRunExternalId, message, level, this.retryCount(), extra === null || extra === void 0 ? void 0 : extra.extra));
|
|
220
220
|
return Promise.all(promises);
|
|
221
221
|
}
|
|
222
222
|
get logger() {
|
|
@@ -249,13 +249,13 @@ class Context {
|
|
|
249
249
|
*/
|
|
250
250
|
refreshTimeout(incrementBy) {
|
|
251
251
|
return __awaiter(this, void 0, void 0, function* () {
|
|
252
|
-
const {
|
|
253
|
-
if (!
|
|
252
|
+
const { taskRunExternalId } = this.action;
|
|
253
|
+
if (!taskRunExternalId) {
|
|
254
254
|
// log a warning
|
|
255
255
|
this._logger.warn('cannot refresh timeout from context without stepRunId');
|
|
256
256
|
return;
|
|
257
257
|
}
|
|
258
|
-
yield this.v1._v0.dispatcher.refreshTimeout(incrementBy,
|
|
258
|
+
yield this.v1._v0.dispatcher.refreshTimeout(incrementBy, taskRunExternalId);
|
|
259
259
|
});
|
|
260
260
|
}
|
|
261
261
|
/**
|
|
@@ -266,7 +266,7 @@ class Context {
|
|
|
266
266
|
releaseSlot() {
|
|
267
267
|
return __awaiter(this, void 0, void 0, function* () {
|
|
268
268
|
yield this.v1._v0.dispatcher.client.releaseSlot({
|
|
269
|
-
|
|
269
|
+
taskRunExternalId: this.action.taskRunExternalId,
|
|
270
270
|
});
|
|
271
271
|
});
|
|
272
272
|
}
|
|
@@ -277,14 +277,14 @@ class Context {
|
|
|
277
277
|
*/
|
|
278
278
|
putStream(data) {
|
|
279
279
|
return __awaiter(this, void 0, void 0, function* () {
|
|
280
|
-
const {
|
|
281
|
-
if (!
|
|
280
|
+
const { taskRunExternalId } = this.action;
|
|
281
|
+
if (!taskRunExternalId) {
|
|
282
282
|
// log a warning
|
|
283
283
|
this._logger.warn('cannot log from context without stepRunId');
|
|
284
284
|
return;
|
|
285
285
|
}
|
|
286
286
|
const index = this._incrementStreamIndex();
|
|
287
|
-
yield this.v1._v0.event.putStream(
|
|
287
|
+
yield this.v1._v0.event.putStream(taskRunExternalId, data, index);
|
|
288
288
|
});
|
|
289
289
|
}
|
|
290
290
|
spawnOptions(workflow, options) {
|
|
@@ -300,8 +300,8 @@ class Context {
|
|
|
300
300
|
if (sticky && !this.worker.hasWorkflow(workflowName)) {
|
|
301
301
|
throw new hatchet_error_1.default(`Cannot run with sticky: workflow ${workflowName} is not registered on the worker`);
|
|
302
302
|
}
|
|
303
|
-
const { workflowRunId,
|
|
304
|
-
const finalOpts = Object.assign(Object.assign({}, options), { parentId: workflowRunId,
|
|
303
|
+
const { workflowRunId, taskRunExternalId } = this.action;
|
|
304
|
+
const finalOpts = Object.assign(Object.assign({}, options), { parentId: workflowRunId, parentTaskRunExternalId: taskRunExternalId, childIndex: this.spawnIndex, childKey: options === null || options === void 0 ? void 0 : options.key, desiredWorkerId: sticky ? this.worker.id() : undefined, _standaloneTaskName: workflow instanceof declaration_1.TaskWorkflowDeclaration ? workflow._standalone_task_name : undefined });
|
|
305
305
|
this.spawnIndex += 1;
|
|
306
306
|
return { workflowName, opts: finalOpts };
|
|
307
307
|
}
|
|
@@ -452,7 +452,7 @@ class Context {
|
|
|
452
452
|
*/
|
|
453
453
|
spawnWorkflows(workflows) {
|
|
454
454
|
return __awaiter(this, void 0, void 0, function* () {
|
|
455
|
-
const { workflowRunId,
|
|
455
|
+
const { workflowRunId, taskRunExternalId } = this.action;
|
|
456
456
|
const workflowRuns = workflows.map(({ workflow, input, options }) => {
|
|
457
457
|
let workflowName;
|
|
458
458
|
if (typeof workflow === 'string') {
|
|
@@ -470,7 +470,7 @@ class Context {
|
|
|
470
470
|
const resp = {
|
|
471
471
|
workflowName: name,
|
|
472
472
|
input,
|
|
473
|
-
options: Object.assign(Object.assign({}, opts), { parentId: workflowRunId,
|
|
473
|
+
options: Object.assign(Object.assign({}, opts), { parentId: workflowRunId, parentTaskRunExternalId: taskRunExternalId, childIndex: this.spawnIndex, desiredWorkerId: sticky ? this.worker.id() : undefined }),
|
|
474
474
|
};
|
|
475
475
|
this.spawnIndex += 1;
|
|
476
476
|
return resp;
|
|
@@ -510,7 +510,7 @@ class Context {
|
|
|
510
510
|
*/
|
|
511
511
|
spawnWorkflow(workflow, input, options) {
|
|
512
512
|
return __awaiter(this, void 0, void 0, function* () {
|
|
513
|
-
const { workflowRunId,
|
|
513
|
+
const { workflowRunId, taskRunExternalId } = this.action;
|
|
514
514
|
let workflowName = '';
|
|
515
515
|
if (typeof workflow === 'string') {
|
|
516
516
|
workflowName = workflow;
|
|
@@ -525,7 +525,7 @@ class Context {
|
|
|
525
525
|
throw new hatchet_error_1.default(`cannot run with sticky: workflow ${name} is not registered on the worker`);
|
|
526
526
|
}
|
|
527
527
|
try {
|
|
528
|
-
const resp = yield this.v1._v0.admin.runWorkflow(name, input, Object.assign({ parentId: workflowRunId,
|
|
528
|
+
const resp = yield this.v1._v0.admin.runWorkflow(name, input, Object.assign({ parentId: workflowRunId, parentTaskRunExternalId: taskRunExternalId, childIndex: this.spawnIndex, desiredWorkerId: sticky ? this.worker.id() : undefined }, opts));
|
|
529
529
|
this.spawnIndex += 1;
|
|
530
530
|
if (workflow instanceof declaration_1.TaskWorkflowDeclaration) {
|
|
531
531
|
resp._standaloneTaskName = workflow._standalone_task_name;
|
|
@@ -572,13 +572,13 @@ class DurableContext extends Context {
|
|
|
572
572
|
// eslint-disable-next-line no-plusplus
|
|
573
573
|
const key = `waitFor-${this.waitKey++}`;
|
|
574
574
|
yield this.v1._v0.durableListener.registerDurableEvent({
|
|
575
|
-
taskId: this.action.
|
|
575
|
+
taskId: this.action.taskRunExternalId,
|
|
576
576
|
signalKey: key,
|
|
577
577
|
sleepConditions: pbConditions.sleepConditions,
|
|
578
578
|
userEventConditions: pbConditions.userEventConditions,
|
|
579
579
|
});
|
|
580
580
|
const listener = this.v1._v0.durableListener.subscribe({
|
|
581
|
-
taskId: this.action.
|
|
581
|
+
taskId: this.action.taskRunExternalId,
|
|
582
582
|
signalKey: key,
|
|
583
583
|
});
|
|
584
584
|
const event = yield listener.get();
|
|
@@ -26,8 +26,8 @@ export declare class V1Worker {
|
|
|
26
26
|
action_registry: ActionRegistry;
|
|
27
27
|
workflow_registry: Array<WorkflowDefinition | Workflow>;
|
|
28
28
|
listener: ActionListener | undefined;
|
|
29
|
-
futures: Record<Action['
|
|
30
|
-
contexts: Record<Action['
|
|
29
|
+
futures: Record<Action['taskRunExternalId'], HatchetPromise<any>>;
|
|
30
|
+
contexts: Record<Action['taskRunExternalId'], Context<any, any>>;
|
|
31
31
|
maxRuns?: number;
|
|
32
32
|
logger: Logger;
|
|
33
33
|
registeredWorkflowPromises: Array<Promise<any>>;
|
|
@@ -398,11 +398,11 @@ class V1Worker {
|
|
|
398
398
|
}
|
|
399
399
|
handleStartStepRun(action) {
|
|
400
400
|
return __awaiter(this, void 0, void 0, function* () {
|
|
401
|
-
const { actionId } = action;
|
|
401
|
+
const { actionId, taskRunExternalId } = action;
|
|
402
402
|
try {
|
|
403
403
|
// Note: we always use a DurableContext since its a superset of the Context class
|
|
404
404
|
const context = new context_1.DurableContext(action, this.client, this);
|
|
405
|
-
this.contexts[
|
|
405
|
+
this.contexts[taskRunExternalId] = context;
|
|
406
406
|
const step = this.action_registry[actionId];
|
|
407
407
|
if (!step) {
|
|
408
408
|
this.logger.error(`Registered actions: '${Object.keys(this.action_registry).join(', ')}'`);
|
|
@@ -412,7 +412,7 @@ class V1Worker {
|
|
|
412
412
|
const run = () => __awaiter(this, void 0, void 0, function* () {
|
|
413
413
|
parent_run_context_vars_1.parentRunContextManager.setContext({
|
|
414
414
|
parentId: action.workflowRunId,
|
|
415
|
-
|
|
415
|
+
parentTaskRunExternalId: taskRunExternalId,
|
|
416
416
|
childIndex: 0,
|
|
417
417
|
desiredWorkerId: this.workerId || '',
|
|
418
418
|
});
|
|
@@ -423,7 +423,7 @@ class V1Worker {
|
|
|
423
423
|
if (context.cancelled) {
|
|
424
424
|
return;
|
|
425
425
|
}
|
|
426
|
-
this.logger.info(`Task run ${
|
|
426
|
+
this.logger.info(`Task run ${taskRunExternalId} succeeded`);
|
|
427
427
|
// Send the action event to the dispatcher
|
|
428
428
|
const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_COMPLETED, false, result || null, action.retryCount);
|
|
429
429
|
yield this.client._v0.dispatcher.sendStepActionEvent(event);
|
|
@@ -442,8 +442,8 @@ class V1Worker {
|
|
|
442
442
|
}
|
|
443
443
|
finally {
|
|
444
444
|
// delete the run from the futures
|
|
445
|
-
delete this.futures[
|
|
446
|
-
delete this.contexts[
|
|
445
|
+
delete this.futures[taskRunExternalId];
|
|
446
|
+
delete this.contexts[taskRunExternalId];
|
|
447
447
|
}
|
|
448
448
|
});
|
|
449
449
|
const failure = (error) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -452,7 +452,7 @@ class V1Worker {
|
|
|
452
452
|
if (context.cancelled) {
|
|
453
453
|
return;
|
|
454
454
|
}
|
|
455
|
-
this.logger.error(`Task run ${
|
|
455
|
+
this.logger.error(`Task run ${taskRunExternalId} failed: ${error.message}`);
|
|
456
456
|
if (error.stack) {
|
|
457
457
|
this.logger.error(error.stack);
|
|
458
458
|
}
|
|
@@ -468,8 +468,8 @@ class V1Worker {
|
|
|
468
468
|
}
|
|
469
469
|
finally {
|
|
470
470
|
// delete the run from the futures
|
|
471
|
-
delete this.futures[
|
|
472
|
-
delete this.contexts[
|
|
471
|
+
delete this.futures[taskRunExternalId];
|
|
472
|
+
delete this.contexts[taskRunExternalId];
|
|
473
473
|
}
|
|
474
474
|
});
|
|
475
475
|
const future = new hatchet_promise_1.default((() => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -483,7 +483,7 @@ class V1Worker {
|
|
|
483
483
|
}
|
|
484
484
|
yield success(result);
|
|
485
485
|
}))());
|
|
486
|
-
this.futures[
|
|
486
|
+
this.futures[taskRunExternalId] = future;
|
|
487
487
|
// Send the action event to the dispatcher
|
|
488
488
|
const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_STARTED, false, undefined, action.retryCount);
|
|
489
489
|
this.client._v0.dispatcher.sendStepActionEvent(event).catch((e) => {
|
|
@@ -495,10 +495,10 @@ class V1Worker {
|
|
|
495
495
|
catch (e) {
|
|
496
496
|
const message = (e === null || e === void 0 ? void 0 : e.message) || String(e);
|
|
497
497
|
if (message.includes('Cancelled')) {
|
|
498
|
-
this.logger.debug(`Task run ${
|
|
498
|
+
this.logger.debug(`Task run ${taskRunExternalId} was cancelled`);
|
|
499
499
|
}
|
|
500
500
|
else {
|
|
501
|
-
this.logger.error(`Could not wait for task run ${
|
|
501
|
+
this.logger.error(`Could not wait for task run ${taskRunExternalId} to finish. ` +
|
|
502
502
|
`See https://docs.hatchet.run/home/cancellation for best practices on handling cancellation: `, e);
|
|
503
503
|
}
|
|
504
504
|
}
|
|
@@ -510,11 +510,11 @@ class V1Worker {
|
|
|
510
510
|
}
|
|
511
511
|
handleStartGroupKeyRun(action) {
|
|
512
512
|
return __awaiter(this, void 0, void 0, function* () {
|
|
513
|
-
const { actionId } = action;
|
|
513
|
+
const { actionId, getGroupKeyRunId, taskRunExternalId } = action;
|
|
514
514
|
this.logger.error('Concurrency Key Functions have been deprecated and will be removed in a future release. Use Concurrency Expressions instead.');
|
|
515
515
|
try {
|
|
516
516
|
const context = new context_1.Context(action, this.client, this);
|
|
517
|
-
const key =
|
|
517
|
+
const key = getGroupKeyRunId;
|
|
518
518
|
if (!key) {
|
|
519
519
|
this.logger.error(`No group key run id provided for action ${actionId}`);
|
|
520
520
|
return;
|
|
@@ -530,7 +530,7 @@ class V1Worker {
|
|
|
530
530
|
return step(context);
|
|
531
531
|
});
|
|
532
532
|
const success = (result) => {
|
|
533
|
-
this.logger.info(`Task run ${
|
|
533
|
+
this.logger.info(`Task run ${taskRunExternalId} succeeded`);
|
|
534
534
|
try {
|
|
535
535
|
// Send the action event to the dispatcher
|
|
536
536
|
const event = this.getGroupKeyActionEvent(action, dispatcher_1.GroupKeyActionEventType.GROUP_KEY_EVENT_TYPE_COMPLETED, result);
|
|
@@ -584,8 +584,8 @@ class V1Worker {
|
|
|
584
584
|
workerId: this.name,
|
|
585
585
|
jobId: action.jobId,
|
|
586
586
|
jobRunId: action.jobRunId,
|
|
587
|
-
|
|
588
|
-
|
|
587
|
+
taskId: action.taskId,
|
|
588
|
+
taskRunExternalId: action.taskRunExternalId,
|
|
589
589
|
actionId: action.actionId,
|
|
590
590
|
eventTimestamp: new Date(),
|
|
591
591
|
eventType,
|
|
@@ -610,17 +610,17 @@ class V1Worker {
|
|
|
610
610
|
}
|
|
611
611
|
handleCancelStepRun(action) {
|
|
612
612
|
return __awaiter(this, void 0, void 0, function* () {
|
|
613
|
-
const {
|
|
613
|
+
const { taskRunExternalId } = action;
|
|
614
614
|
try {
|
|
615
|
-
this.logger.info(`Cancelling task run ${
|
|
616
|
-
const future = this.futures[
|
|
617
|
-
const context = this.contexts[
|
|
615
|
+
this.logger.info(`Cancelling task run ${taskRunExternalId}`);
|
|
616
|
+
const future = this.futures[taskRunExternalId];
|
|
617
|
+
const context = this.contexts[taskRunExternalId];
|
|
618
618
|
if (context && context.abortController) {
|
|
619
619
|
context.abortController.abort('Cancelled by worker');
|
|
620
620
|
}
|
|
621
621
|
if (future) {
|
|
622
622
|
future.promise.catch(() => {
|
|
623
|
-
this.logger.info(`Cancelled task run ${
|
|
623
|
+
this.logger.info(`Cancelled task run ${taskRunExternalId}`);
|
|
624
624
|
});
|
|
625
625
|
future.cancel('Cancelled by worker');
|
|
626
626
|
yield future.promise;
|
|
@@ -628,11 +628,11 @@ class V1Worker {
|
|
|
628
628
|
}
|
|
629
629
|
catch (e) {
|
|
630
630
|
// Expected: the promise rejects when cancelled
|
|
631
|
-
this.logger.debug(`Task run ${
|
|
631
|
+
this.logger.debug(`Task run ${taskRunExternalId} cancellation completed`);
|
|
632
632
|
}
|
|
633
633
|
finally {
|
|
634
|
-
delete this.futures[
|
|
635
|
-
delete this.contexts[
|
|
634
|
+
delete this.futures[taskRunExternalId];
|
|
635
|
+
delete this.contexts[taskRunExternalId];
|
|
636
636
|
}
|
|
637
637
|
});
|
|
638
638
|
}
|