@hatchet-dev/typescript-sdk 1.13.0 → 1.14.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/dispatcher/dispatcher-client.d.ts +1 -1
- package/clients/dispatcher/heartbeat/heartbeat-controller.js +13 -1
- package/clients/dispatcher/heartbeat/heartbeat-worker.js +4 -3
- package/clients/event/event-client.d.ts +1 -2
- package/clients/event/event-client.js +2 -2
- package/clients/hatchet-client/client-config.d.ts +15 -5
- package/clients/hatchet-client/client-config.js +3 -0
- package/clients/hatchet-client/hatchet-logger.js +1 -0
- package/clients/hatchet-client/index.d.ts +1 -1
- package/clients/hatchet-client/index.js +1 -1
- package/clients/listeners/durable-listener/durable-listener-client.d.ts +6 -0
- package/clients/listeners/durable-listener/durable-listener-client.js +8 -0
- package/clients/listeners/durable-listener/pooled-durable-listener-client.d.ts +9 -2
- package/clients/listeners/durable-listener/pooled-durable-listener-client.js +67 -15
- package/clients/listeners/run-listener/child-listener-client.js +1 -0
- package/clients/listeners/run-listener/pooled-child-listener-client.d.ts +10 -2
- package/clients/listeners/run-listener/pooled-child-listener-client.js +63 -7
- package/clients/rest/api.js +10 -2
- package/clients/rest/generated/Api.d.ts +2 -2
- package/clients/rest/generated/data-contracts.d.ts +6 -0
- package/index.d.ts +2 -3
- package/index.js +2 -3
- package/{examples → legacy/examples}/affinity-workers.js +2 -2
- package/{examples → legacy/examples}/bulk-fanout-trigger.js +1 -1
- package/{examples → legacy/examples}/bulk-fanout-worker.js +1 -1
- package/{examples → legacy/examples}/bulk-trigger.js +1 -1
- package/{examples → legacy/examples}/byo-logger.js +1 -1
- package/{examples → legacy/examples}/concurrency/cancel-in-progress/concurrency-event.js +1 -1
- package/{examples → legacy/examples}/concurrency/cancel-in-progress/concurrency-worker.js +1 -1
- package/{examples → legacy/examples}/concurrency/group-round-robin/concurrency-event.js +1 -1
- package/{examples → legacy/examples}/concurrency/group-round-robin/concurrency-worker-expression.js +2 -2
- package/{examples → legacy/examples}/concurrency/group-round-robin/concurrency-worker-key-fn.js +2 -2
- package/{examples → legacy/examples}/crons/cron-worker.d.ts +1 -1
- package/{examples → legacy/examples}/crons/cron-worker.js +1 -1
- package/{examples → legacy/examples}/crons/programatic-crons.js +1 -1
- package/{examples → legacy/examples}/dag-worker.js +1 -1
- package/{examples → legacy/examples}/example-event-with-results.js +2 -2
- package/{examples → legacy/examples}/example-event.js +1 -1
- package/{examples → legacy/examples}/fanout-worker.js +1 -1
- package/{examples → legacy/examples}/logger.js +1 -1
- package/{examples → legacy/examples}/manual-trigger.js +1 -1
- package/{examples → legacy/examples}/multi-workflow.js +1 -1
- package/{examples → legacy/examples}/namespaced-worker.js +1 -1
- package/{examples → legacy/examples}/on-failure.js +1 -1
- package/{examples → legacy/examples}/rate-limit/events.js +1 -1
- package/{examples → legacy/examples}/rate-limit/worker.js +2 -2
- package/{examples → legacy/examples}/retries-with-backoff.js +1 -1
- package/{examples → legacy/examples}/retries-worker.js +1 -1
- package/{examples → legacy/examples}/scheduled-runs/programatic-schedules.js +1 -1
- package/{examples → legacy/examples}/simple-worker.d.ts +1 -1
- package/{examples → legacy/examples}/simple-worker.js +1 -1
- package/{examples → legacy/examples}/sticky-trigger.js +1 -1
- package/{examples → legacy/examples}/sticky-worker-with-check.js +2 -2
- package/{examples → legacy/examples}/sticky-worker.js +2 -2
- package/{examples → legacy/examples}/stream-by-additional-meta.js +2 -2
- package/legacy/legacy-client.d.ts +30 -0
- package/legacy/legacy-client.js +67 -0
- package/legacy/legacy-transformer.d.ts +38 -0
- package/legacy/legacy-transformer.js +181 -0
- package/legacy/step.d.ts +429 -0
- package/legacy/step.js +662 -0
- package/legacy/workflow.d.ts +488 -0
- package/legacy/workflow.js +72 -0
- package/package.json +7 -7
- package/step.d.ts +1 -430
- package/step.js +6 -647
- package/util/abort-error.d.ts +38 -0
- package/util/abort-error.js +58 -0
- package/util/hatchet-promise/hatchet-promise.d.ts +8 -1
- package/util/hatchet-promise/hatchet-promise.js +3 -2
- package/util/logger/index.d.ts +1 -0
- package/util/logger/index.js +1 -0
- package/util/logger/task-run-log.d.ts +3 -0
- package/util/logger/task-run-log.js +20 -0
- package/util/sleep.d.ts +5 -2
- package/util/sleep.js +27 -4
- package/util/workflow-run-ref.d.ts +7 -1
- package/util/workflow-run-ref.js +5 -3
- package/v1/client/admin.d.ts +8 -1
- package/v1/client/admin.js +22 -6
- package/v1/client/client.d.ts +36 -18
- package/v1/client/client.interface.d.ts +9 -2
- package/v1/client/client.js +47 -27
- package/v1/client/features/crons.d.ts +3 -3
- package/v1/client/features/crons.js +2 -2
- package/v1/client/features/schedules.js +2 -2
- package/v1/client/features/workflows.d.ts +5 -5
- package/v1/client/features/workflows.js +7 -8
- package/v1/client/worker/context.d.ts +49 -10
- package/v1/client/worker/context.js +92 -20
- package/v1/client/worker/deprecated/legacy-v1-worker.d.ts +3 -3
- package/v1/client/worker/deprecated/legacy-v1-worker.js +2 -2
- package/v1/client/worker/deprecated/legacy-worker.js +9 -7
- package/v1/client/worker/slot-utils.d.ts +3 -3
- package/v1/client/worker/worker-internal.d.ts +7 -16
- package/v1/client/worker/worker-internal.js +225 -209
- package/v1/client/worker/worker.d.ts +18 -18
- package/v1/client/worker/worker.js +45 -30
- package/v1/declaration.d.ts +28 -7
- package/v1/declaration.js +56 -6
- package/v1/examples/__e2e__/harness.d.ts +19 -0
- package/v1/examples/__e2e__/harness.js +70 -0
- package/v1/examples/affinity/affinity-workers.js +4 -4
- package/v1/examples/bulk_fanout/workflow.d.ts +9 -0
- package/v1/examples/bulk_fanout/workflow.js +34 -0
- package/v1/examples/bulk_operations/workflow.d.ts +3 -0
- package/v1/examples/bulk_operations/workflow.js +44 -0
- package/v1/examples/cancellation/cancellation-workflow.d.ts +2 -0
- package/v1/examples/cancellation/cancellation-workflow.js +69 -0
- package/v1/examples/cancellation/run.js +53 -0
- package/v1/examples/cancellation/worker.d.ts +1 -0
- package/v1/examples/cancellation/worker.js +29 -0
- package/v1/examples/concurrency-types.d.ts +5 -0
- package/v1/examples/concurrency-types.js +2 -0
- package/v1/examples/concurrency_cancel_in_progress/workflow.d.ts +9 -0
- package/v1/examples/concurrency_cancel_in_progress/workflow.js +45 -0
- package/v1/examples/concurrency_cancel_newest/workflow.d.ts +9 -0
- package/v1/examples/concurrency_cancel_newest/workflow.js +45 -0
- package/v1/examples/concurrency_limit_rr/load.d.ts +1 -0
- package/v1/examples/concurrency_limit_rr/load.js +54 -0
- package/v1/examples/concurrency_limit_rr/run.d.ts +1 -0
- package/v1/examples/concurrency_limit_rr/run.js +39 -0
- package/v1/examples/concurrency_limit_rr/worker.d.ts +1 -0
- package/v1/examples/concurrency_limit_rr/worker.js +24 -0
- package/v1/examples/concurrency_limit_rr/workflow.d.ts +12 -0
- package/v1/examples/concurrency_limit_rr/workflow.js +62 -0
- package/v1/examples/concurrency_multiple_keys/workflow.d.ts +12 -0
- package/v1/examples/concurrency_multiple_keys/workflow.js +42 -0
- package/v1/examples/concurrency_workflow_level/workflow.d.ts +13 -0
- package/v1/examples/concurrency_workflow_level/workflow.js +49 -0
- package/v1/examples/conditions/complex-workflow.d.ts +1 -0
- package/v1/examples/conditions/complex-workflow.js +107 -0
- package/v1/examples/conditions/event.d.ts +1 -0
- package/v1/examples/conditions/event.js +28 -0
- package/v1/examples/conditions/run.d.ts +1 -0
- package/v1/examples/conditions/run.js +25 -0
- package/v1/examples/conditions/worker.d.ts +1 -0
- package/v1/examples/conditions/worker.js +24 -0
- package/v1/examples/conditions/workflow.d.ts +11 -0
- package/v1/examples/conditions/workflow.js +41 -0
- package/v1/examples/durable/workflow.d.ts +7 -0
- package/v1/examples/durable/workflow.js +116 -0
- package/v1/examples/durable_event/event.d.ts +1 -0
- package/v1/examples/durable_event/event.js +28 -0
- package/v1/examples/durable_event/run.d.ts +1 -0
- package/v1/examples/durable_event/run.js +30 -0
- package/v1/examples/durable_event/worker.d.ts +1 -0
- package/v1/examples/durable_event/worker.js +24 -0
- package/v1/examples/durable_event/workflow.d.ts +6 -0
- package/v1/examples/durable_event/workflow.js +46 -0
- package/v1/examples/durable_sleep/event.d.ts +1 -0
- package/v1/examples/durable_sleep/event.js +28 -0
- package/v1/examples/durable_sleep/run.d.ts +1 -0
- package/v1/examples/durable_sleep/run.js +30 -0
- package/v1/examples/durable_sleep/worker.d.ts +1 -0
- package/v1/examples/durable_sleep/worker.js +24 -0
- package/v1/examples/durable_sleep/workflow.d.ts +1 -0
- package/v1/examples/durable_sleep/workflow.js +31 -0
- package/v1/examples/e2e-worker.d.ts +1 -0
- package/v1/examples/e2e-worker.js +82 -0
- package/v1/examples/events/event.d.ts +1 -0
- package/v1/examples/events/event.js +53 -0
- package/v1/examples/events/filter.d.ts +1 -0
- package/v1/examples/events/filter.js +32 -0
- package/v1/examples/events/worker.d.ts +1 -0
- package/v1/examples/events/worker.js +24 -0
- package/v1/examples/events/workflow.d.ts +19 -0
- package/v1/examples/events/workflow.js +60 -0
- package/v1/examples/high-memory/workflow-with-child.js +1 -1
- package/v1/examples/logger/byo-logger.d.ts +1 -0
- package/v1/examples/logger/byo-logger.js +73 -0
- package/v1/examples/logger/logger.d.ts +1 -0
- package/v1/examples/logger/logger.js +46 -0
- package/v1/examples/logger/workflow.d.ts +2 -0
- package/v1/examples/logger/workflow.js +38 -0
- package/v1/examples/multiple_wf_concurrency/workflow.js +3 -3
- package/v1/examples/on_failure/workflow.d.ts +1 -0
- package/v1/examples/on_failure/workflow.js +12 -7
- package/v1/examples/priority/workflow.js +1 -1
- package/v1/examples/retries/workflow.js +2 -2
- package/v1/examples/return_exceptions/workflow.d.ts +6 -0
- package/v1/examples/return_exceptions/workflow.js +22 -0
- package/v1/examples/run_details/workflow.d.ts +4 -0
- package/v1/examples/run_details/workflow.js +65 -0
- package/v1/examples/simple/e2e-workflows.d.ts +14 -0
- package/v1/examples/simple/e2e-workflows.js +27 -0
- package/v1/examples/simple/enqueue.js +2 -2
- package/v1/examples/sticky/workflow.js +2 -2
- package/v1/examples/timeout/run.d.ts +1 -0
- package/v1/examples/timeout/run.js +30 -0
- package/v1/examples/timeout/worker.d.ts +1 -0
- package/v1/examples/timeout/worker.js +25 -0
- package/v1/examples/timeout/workflow.d.ts +10 -0
- package/v1/examples/timeout/workflow.js +56 -0
- package/v1/examples/webhooks/workflow.d.ts +5 -0
- package/v1/examples/webhooks/workflow.js +23 -0
- package/v1/index.d.ts +1 -0
- package/v1/index.js +1 -0
- package/v1/parent-run-context-vars.d.ts +6 -0
- package/v1/parent-run-context-vars.js +3 -0
- package/v1/task.d.ts +22 -7
- package/v1/task.js +4 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/workflow.d.ts +3 -491
- package/workflow.js +12 -62
- package/clients/hatchet-client/hatchet-client.d.ts +0 -35
- package/clients/hatchet-client/hatchet-client.js +0 -108
- package/clients/worker/handler.d.ts +0 -50
- package/clients/worker/handler.js +0 -214
- package/clients/worker/index.d.ts +0 -1
- package/clients/worker/index.js +0 -17
- package/clients/worker/worker.d.ts +0 -59
- package/clients/worker/worker.js +0 -568
- package/examples/webhooks.js +0 -45
- /package/{examples → legacy/examples}/affinity-workers.d.ts +0 -0
- /package/{examples → legacy/examples}/bulk-fanout-trigger.d.ts +0 -0
- /package/{examples → legacy/examples}/bulk-fanout-worker.d.ts +0 -0
- /package/{examples → legacy/examples}/bulk-trigger.d.ts +0 -0
- /package/{examples → legacy/examples}/byo-logger.d.ts +0 -0
- /package/{examples → legacy/examples}/concurrency/cancel-in-progress/concurrency-event.d.ts +0 -0
- /package/{examples → legacy/examples}/concurrency/cancel-in-progress/concurrency-worker.d.ts +0 -0
- /package/{examples → legacy/examples}/concurrency/group-round-robin/concurrency-event.d.ts +0 -0
- /package/{examples → legacy/examples}/concurrency/group-round-robin/concurrency-worker-expression.d.ts +0 -0
- /package/{examples → legacy/examples}/concurrency/group-round-robin/concurrency-worker-key-fn.d.ts +0 -0
- /package/{examples → legacy/examples}/crons/programatic-crons.d.ts +0 -0
- /package/{examples → legacy/examples}/dag-worker.d.ts +0 -0
- /package/{examples → legacy/examples}/example-event-with-results.d.ts +0 -0
- /package/{examples → legacy/examples}/example-event.d.ts +0 -0
- /package/{examples → legacy/examples}/fanout-worker.d.ts +0 -0
- /package/{examples → legacy/examples}/logger.d.ts +0 -0
- /package/{examples → legacy/examples}/manual-trigger.d.ts +0 -0
- /package/{examples → legacy/examples}/multi-workflow.d.ts +0 -0
- /package/{examples → legacy/examples}/namespaced-worker.d.ts +0 -0
- /package/{examples → legacy/examples}/on-failure.d.ts +0 -0
- /package/{examples → legacy/examples}/rate-limit/events.d.ts +0 -0
- /package/{examples → legacy/examples}/rate-limit/worker.d.ts +0 -0
- /package/{examples → legacy/examples}/retries-with-backoff.d.ts +0 -0
- /package/{examples → legacy/examples}/retries-worker.d.ts +0 -0
- /package/{examples → legacy/examples}/scheduled-runs/programatic-schedules.d.ts +0 -0
- /package/{examples → legacy/examples}/sticky-trigger.d.ts +0 -0
- /package/{examples → legacy/examples}/sticky-worker-with-check.d.ts +0 -0
- /package/{examples → legacy/examples}/sticky-worker.d.ts +0 -0
- /package/{examples → legacy/examples}/stream-by-additional-meta.d.ts +0 -0
- /package/{examples/webhooks.d.ts → v1/examples/cancellation/run.d.ts} +0 -0
|
@@ -19,22 +19,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
19
19
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.
|
|
22
|
+
exports.InternalWorker = void 0;
|
|
23
|
+
exports.mapRateLimitPb = mapRateLimitPb;
|
|
23
24
|
/* eslint-disable no-underscore-dangle */
|
|
24
25
|
/* eslint-disable no-nested-ternary */
|
|
25
26
|
const hatchet_error_1 = __importDefault(require("../../../util/errors/hatchet-error"));
|
|
26
27
|
const dispatcher_1 = require("../../../protoc/dispatcher");
|
|
27
28
|
const hatchet_promise_1 = __importDefault(require("../../../util/hatchet-promise/hatchet-promise"));
|
|
28
29
|
const workflows_1 = require("../../../protoc/workflows");
|
|
30
|
+
const logger_1 = require("../../../util/logger");
|
|
29
31
|
const task_1 = require("../../task");
|
|
30
32
|
const transformer_1 = require("../../conditions/transformer");
|
|
31
33
|
const zod_to_json_schema_1 = require("zod-to-json-schema");
|
|
32
|
-
const step_1 = require("../../../step");
|
|
33
34
|
const apply_namespace_1 = require("../../../util/apply-namespace");
|
|
35
|
+
const sleep_1 = __importDefault(require("../../../util/sleep"));
|
|
36
|
+
const abort_error_1 = require("../../../util/abort-error");
|
|
34
37
|
const context_1 = require("./context");
|
|
35
38
|
const parent_run_context_vars_1 = require("../../parent-run-context-vars");
|
|
36
39
|
const health_server_1 = require("./health-server");
|
|
37
|
-
class
|
|
40
|
+
class InternalWorker {
|
|
38
41
|
constructor(client, options) {
|
|
39
42
|
var _a, _b, _c, _d;
|
|
40
43
|
this.workflow_registry = [];
|
|
@@ -90,48 +93,7 @@ class V1Worker {
|
|
|
90
93
|
this.status = status;
|
|
91
94
|
this.logger.debug(`Worker status changed to: ${status}`);
|
|
92
95
|
}
|
|
93
|
-
|
|
94
|
-
var _a;
|
|
95
|
-
const newActions = workflow.steps.reduce((acc, step) => {
|
|
96
|
-
acc[`${workflow.id}:${step.name.toLowerCase()}`] = step.run;
|
|
97
|
-
return acc;
|
|
98
|
-
}, {});
|
|
99
|
-
const onFailureAction = workflow.onFailure
|
|
100
|
-
? {
|
|
101
|
-
[`${workflow.id}-on-failure:${workflow.onFailure.name}`]: workflow.onFailure.run,
|
|
102
|
-
}
|
|
103
|
-
: {};
|
|
104
|
-
this.action_registry = Object.assign(Object.assign(Object.assign({}, this.action_registry), newActions), onFailureAction);
|
|
105
|
-
this.action_registry =
|
|
106
|
-
((_a = workflow.concurrency) === null || _a === void 0 ? void 0 : _a.name) && workflow.concurrency.key
|
|
107
|
-
? Object.assign(Object.assign({}, this.action_registry), { [`${workflow.id}:${workflow.concurrency.name.toLowerCase()}`]: workflow.concurrency.key }) : Object.assign({}, this.action_registry);
|
|
108
|
-
}
|
|
109
|
-
getHandler(workflows) {
|
|
110
|
-
throw new Error('Not implemented');
|
|
111
|
-
// TODO v1
|
|
112
|
-
// for (const workflow of workflows) {
|
|
113
|
-
// const wf: Workflow = {
|
|
114
|
-
// ...workflow,
|
|
115
|
-
// id: this.client.config.namespace + workflow.id,
|
|
116
|
-
// };
|
|
117
|
-
// this.registerActions(wf);
|
|
118
|
-
// }
|
|
119
|
-
// return new WebhookHandler(this, workflows);
|
|
120
|
-
}
|
|
121
|
-
registerWebhook(webhook) {
|
|
122
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
123
|
-
return this.client._v0.admin.registerWebhook(Object.assign({}, webhook));
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* @deprecated use registerWorkflow instead
|
|
128
|
-
*/
|
|
129
|
-
register_workflow(initWorkflow) {
|
|
130
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
-
return this.registerWorkflow(initWorkflow);
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
registerDurableActionsV1(workflow) {
|
|
96
|
+
registerDurableActions(workflow) {
|
|
135
97
|
const newActions = workflow._durableTasks
|
|
136
98
|
.filter((task) => !!task.fn)
|
|
137
99
|
.reduce((acc, task) => {
|
|
@@ -140,7 +102,7 @@ class V1Worker {
|
|
|
140
102
|
}, {});
|
|
141
103
|
this.action_registry = Object.assign(Object.assign({}, this.action_registry), newActions);
|
|
142
104
|
}
|
|
143
|
-
|
|
105
|
+
registerActions(workflow) {
|
|
144
106
|
const newActions = workflow._tasks
|
|
145
107
|
.filter((task) => !!task.fn)
|
|
146
108
|
.reduce((acc, task) => {
|
|
@@ -159,9 +121,9 @@ class V1Worker {
|
|
|
159
121
|
: {};
|
|
160
122
|
this.action_registry = Object.assign(Object.assign(Object.assign({}, this.action_registry), newActions), onFailureAction);
|
|
161
123
|
}
|
|
162
|
-
|
|
124
|
+
registerWorkflow(initWorkflow_1) {
|
|
163
125
|
return __awaiter(this, arguments, void 0, function* (initWorkflow, durable = false) {
|
|
164
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v
|
|
126
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
165
127
|
// patch the namespace
|
|
166
128
|
const workflow = Object.assign(Object.assign({}, initWorkflow.definition), { name: (0, apply_namespace_1.applyNamespace)(initWorkflow.definition.name, this.client.config.namespace).toLowerCase() });
|
|
167
129
|
try {
|
|
@@ -192,8 +154,8 @@ class V1Worker {
|
|
|
192
154
|
inputs: '{}',
|
|
193
155
|
parents: [],
|
|
194
156
|
retries: onFailure.retries || ((_c = workflow.taskDefaults) === null || _c === void 0 ? void 0 : _c.retries) || 0,
|
|
195
|
-
rateLimits: (
|
|
196
|
-
workerLabels:
|
|
157
|
+
rateLimits: mapRateLimitPb(onFailure.rateLimits || ((_d = workflow.taskDefaults) === null || _d === void 0 ? void 0 : _d.rateLimits)),
|
|
158
|
+
workerLabels: mapWorkerLabelPb(onFailure.desiredWorkerLabels || ((_e = workflow.taskDefaults) === null || _e === void 0 ? void 0 : _e.workerLabels)),
|
|
197
159
|
concurrency: [],
|
|
198
160
|
backoffFactor: ((_f = onFailure.backoff) === null || _f === void 0 ? void 0 : _f.factor) || ((_h = (_g = workflow.taskDefaults) === null || _g === void 0 ? void 0 : _g.backoff) === null || _h === void 0 ? void 0 : _h.factor),
|
|
199
161
|
backoffMaxSeconds: ((_j = onFailure.backoff) === null || _j === void 0 ? void 0 : _j.maxSeconds) || ((_l = (_k = workflow.taskDefaults) === null || _k === void 0 ? void 0 : _k.backoff) === null || _l === void 0 ? void 0 : _l.maxSeconds),
|
|
@@ -207,11 +169,11 @@ class V1Worker {
|
|
|
207
169
|
onSuccessTask = {
|
|
208
170
|
name: 'on-success-task',
|
|
209
171
|
fn: workflow.onSuccess,
|
|
210
|
-
|
|
172
|
+
executionTimeout: '60s',
|
|
211
173
|
parents,
|
|
212
174
|
retries: 0,
|
|
213
175
|
rateLimits: [],
|
|
214
|
-
desiredWorkerLabels:
|
|
176
|
+
desiredWorkerLabels: undefined,
|
|
215
177
|
concurrency: [],
|
|
216
178
|
};
|
|
217
179
|
}
|
|
@@ -221,7 +183,7 @@ class V1Worker {
|
|
|
221
183
|
onSuccessTask = {
|
|
222
184
|
name: 'on-success-task',
|
|
223
185
|
fn: onSuccess.fn,
|
|
224
|
-
|
|
186
|
+
executionTimeout: onSuccess.executionTimeout || ((_m = workflow.taskDefaults) === null || _m === void 0 ? void 0 : _m.executionTimeout) || '60s',
|
|
225
187
|
scheduleTimeout: onSuccess.scheduleTimeout || ((_o = workflow.taskDefaults) === null || _o === void 0 ? void 0 : _o.scheduleTimeout),
|
|
226
188
|
parents,
|
|
227
189
|
retries: onSuccess.retries || ((_p = workflow.taskDefaults) === null || _p === void 0 ? void 0 : _p.retries) || 0,
|
|
@@ -234,19 +196,21 @@ class V1Worker {
|
|
|
234
196
|
if (onSuccessTask) {
|
|
235
197
|
workflow._tasks.push(onSuccessTask);
|
|
236
198
|
}
|
|
237
|
-
// cron and event triggers
|
|
238
|
-
if (workflow.on) {
|
|
239
|
-
this.logger.warn(`\`on\` for event and cron triggers is deprecated and will be removed soon, use \`onEvents\` and \`onCrons\` instead for ${workflow.name}`);
|
|
240
|
-
}
|
|
241
199
|
const eventTriggers = [
|
|
242
200
|
...(workflow.onEvents || []).map((event) => (0, apply_namespace_1.applyNamespace)(event, this.client.config.namespace)),
|
|
243
|
-
...(
|
|
244
|
-
?
|
|
201
|
+
...(workflow.on && 'event' in workflow.on && workflow.on.event
|
|
202
|
+
? Array.isArray(workflow.on.event)
|
|
203
|
+
? workflow.on.event.map((event) => (0, apply_namespace_1.applyNamespace)(event, this.client.config.namespace))
|
|
204
|
+
: [(0, apply_namespace_1.applyNamespace)(workflow.on.event, this.client.config.namespace)]
|
|
245
205
|
: []),
|
|
246
206
|
];
|
|
247
207
|
const cronTriggers = [
|
|
248
208
|
...(workflow.onCrons || []),
|
|
249
|
-
...(
|
|
209
|
+
...(workflow.on && 'cron' in workflow.on && workflow.on.cron
|
|
210
|
+
? Array.isArray(workflow.on.cron)
|
|
211
|
+
? workflow.on.cron
|
|
212
|
+
: [workflow.on.cron]
|
|
213
|
+
: []),
|
|
250
214
|
];
|
|
251
215
|
const concurrencyArr = Array.isArray(concurrency) ? concurrency : [];
|
|
252
216
|
const concurrencySolo = !Array.isArray(concurrency) ? concurrency : undefined;
|
|
@@ -258,13 +222,34 @@ class V1Worker {
|
|
|
258
222
|
inputJsonSchema = new TextEncoder().encode(JSON.stringify(jsonSchema));
|
|
259
223
|
}
|
|
260
224
|
const durableTaskSet = new Set(workflow._durableTasks);
|
|
261
|
-
|
|
225
|
+
let stickyStrategy;
|
|
226
|
+
// `workflow.sticky` is optional. When omitted, we don't set any sticky strategy.
|
|
227
|
+
//
|
|
228
|
+
// When provided, `workflow.sticky` is a v1 (non-protobuf) config which may also include
|
|
229
|
+
// legacy protobuf enum values for backwards compatibility.
|
|
230
|
+
if (workflow.sticky != null) {
|
|
231
|
+
switch (workflow.sticky) {
|
|
232
|
+
case 'soft':
|
|
233
|
+
case 'SOFT':
|
|
234
|
+
case 0:
|
|
235
|
+
stickyStrategy = workflows_1.StickyStrategy.SOFT;
|
|
236
|
+
break;
|
|
237
|
+
case 'hard':
|
|
238
|
+
case 'HARD':
|
|
239
|
+
case 1:
|
|
240
|
+
stickyStrategy = workflows_1.StickyStrategy.HARD;
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
throw new hatchet_error_1.default(`Invalid sticky strategy: ${workflow.sticky}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const registeredWorkflow = this.client.admin.putWorkflow({
|
|
262
247
|
name: workflow.name,
|
|
263
248
|
description: workflow.description || '',
|
|
264
249
|
version: workflow.version || '',
|
|
265
250
|
eventTriggers,
|
|
266
251
|
cronTriggers,
|
|
267
|
-
sticky:
|
|
252
|
+
sticky: stickyStrategy,
|
|
268
253
|
concurrencyArr,
|
|
269
254
|
onFailureTask,
|
|
270
255
|
defaultPriority: workflow.defaultPriority,
|
|
@@ -283,8 +268,8 @@ class V1Worker {
|
|
|
283
268
|
parents: (_d = (_c = task.parents) === null || _c === void 0 ? void 0 : _c.map((p) => p.name)) !== null && _d !== void 0 ? _d : [],
|
|
284
269
|
userData: '{}',
|
|
285
270
|
retries: task.retries || ((_e = workflow.taskDefaults) === null || _e === void 0 ? void 0 : _e.retries) || 0,
|
|
286
|
-
rateLimits: (
|
|
287
|
-
workerLabels:
|
|
271
|
+
rateLimits: mapRateLimitPb(task.rateLimits || ((_f = workflow.taskDefaults) === null || _f === void 0 ? void 0 : _f.rateLimits)),
|
|
272
|
+
workerLabels: mapWorkerLabelPb(task.desiredWorkerLabels || ((_g = workflow.taskDefaults) === null || _g === void 0 ? void 0 : _g.workerLabels)),
|
|
288
273
|
backoffFactor: ((_h = task.backoff) === null || _h === void 0 ? void 0 : _h.factor) || ((_k = (_j = workflow.taskDefaults) === null || _j === void 0 ? void 0 : _j.backoff) === null || _k === void 0 ? void 0 : _k.factor),
|
|
289
274
|
backoffMaxSeconds: ((_l = task.backoff) === null || _l === void 0 ? void 0 : _l.maxSeconds) || ((_o = (_m = workflow.taskDefaults) === null || _m === void 0 ? void 0 : _m.backoff) === null || _o === void 0 ? void 0 : _o.maxSeconds),
|
|
290
275
|
conditions: (0, transformer_1.taskConditionsToPb)(task),
|
|
@@ -302,94 +287,11 @@ class V1Worker {
|
|
|
302
287
|
});
|
|
303
288
|
}),
|
|
304
289
|
concurrency: concurrencySolo,
|
|
305
|
-
defaultFilters: (
|
|
290
|
+
defaultFilters: (_v = (_u = workflow.defaultFilters) === null || _u === void 0 ? void 0 : _u.map((f) => ({
|
|
306
291
|
scope: f.scope,
|
|
307
292
|
expression: f.expression,
|
|
308
293
|
payload: f.payload ? new TextEncoder().encode(JSON.stringify(f.payload)) : undefined,
|
|
309
|
-
}))) !== null &&
|
|
310
|
-
});
|
|
311
|
-
this.registeredWorkflowPromises.push(registeredWorkflow);
|
|
312
|
-
yield registeredWorkflow;
|
|
313
|
-
this.workflow_registry.push(workflow);
|
|
314
|
-
}
|
|
315
|
-
catch (e) {
|
|
316
|
-
throw new hatchet_error_1.default(`Could not register workflow: ${e.message}`);
|
|
317
|
-
}
|
|
318
|
-
this.registerActionsV1(workflow);
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
registerWorkflow(initWorkflow) {
|
|
322
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
323
|
-
var _a, _b, _c;
|
|
324
|
-
const workflow = Object.assign(Object.assign({}, initWorkflow), { id: (0, apply_namespace_1.applyNamespace)(initWorkflow.id, this.client.config.namespace).toLowerCase() });
|
|
325
|
-
try {
|
|
326
|
-
if (((_a = workflow.concurrency) === null || _a === void 0 ? void 0 : _a.key) && workflow.concurrency.expression) {
|
|
327
|
-
throw new hatchet_error_1.default('Cannot have both key function and expression in workflow concurrency configuration');
|
|
328
|
-
}
|
|
329
|
-
const concurrency = ((_b = workflow.concurrency) === null || _b === void 0 ? void 0 : _b.name) || ((_c = workflow.concurrency) === null || _c === void 0 ? void 0 : _c.expression)
|
|
330
|
-
? {
|
|
331
|
-
action: !workflow.concurrency.expression
|
|
332
|
-
? `${workflow.id}:${workflow.concurrency.name}`
|
|
333
|
-
: undefined,
|
|
334
|
-
maxRuns: workflow.concurrency.maxRuns || 1,
|
|
335
|
-
expression: workflow.concurrency.expression,
|
|
336
|
-
limitStrategy: workflow.concurrency.limitStrategy || workflows_1.ConcurrencyLimitStrategy.CANCEL_IN_PROGRESS,
|
|
337
|
-
}
|
|
338
|
-
: undefined;
|
|
339
|
-
const onFailureJob = workflow.onFailure
|
|
340
|
-
? {
|
|
341
|
-
name: `${workflow.id}-on-failure`,
|
|
342
|
-
description: workflow.description,
|
|
343
|
-
steps: [
|
|
344
|
-
{
|
|
345
|
-
readableId: workflow.onFailure.name,
|
|
346
|
-
action: `${workflow.id}-on-failure:${workflow.onFailure.name}`,
|
|
347
|
-
timeout: workflow.onFailure.timeout || '60s',
|
|
348
|
-
inputs: '{}',
|
|
349
|
-
parents: [],
|
|
350
|
-
userData: '{}',
|
|
351
|
-
retries: workflow.onFailure.retries || 0,
|
|
352
|
-
rateLimits: (0, step_1.mapRateLimit)(workflow.onFailure.rate_limits),
|
|
353
|
-
workerLabels: {}, // no worker labels for on failure steps
|
|
354
|
-
},
|
|
355
|
-
],
|
|
356
|
-
}
|
|
357
|
-
: undefined;
|
|
358
|
-
const registeredWorkflow = this.client._v0.admin.putWorkflow({
|
|
359
|
-
name: workflow.id,
|
|
360
|
-
description: workflow.description,
|
|
361
|
-
version: workflow.version || '',
|
|
362
|
-
eventTriggers: workflow.on && workflow.on.event
|
|
363
|
-
? [(0, apply_namespace_1.applyNamespace)(workflow.on.event, this.client.config.namespace)]
|
|
364
|
-
: [],
|
|
365
|
-
cronTriggers: workflow.on && workflow.on.cron ? [workflow.on.cron] : [],
|
|
366
|
-
scheduledTriggers: [],
|
|
367
|
-
concurrency,
|
|
368
|
-
scheduleTimeout: workflow.scheduleTimeout,
|
|
369
|
-
onFailureJob,
|
|
370
|
-
sticky: workflow.sticky,
|
|
371
|
-
jobs: [
|
|
372
|
-
{
|
|
373
|
-
name: workflow.id,
|
|
374
|
-
description: workflow.description,
|
|
375
|
-
steps: workflow.steps.map((step) => {
|
|
376
|
-
var _a, _b, _c;
|
|
377
|
-
return ({
|
|
378
|
-
readableId: step.name,
|
|
379
|
-
action: `${workflow.id}:${step.name}`,
|
|
380
|
-
timeout: step.timeout || '60s',
|
|
381
|
-
inputs: '{}',
|
|
382
|
-
parents: (_a = step.parents) !== null && _a !== void 0 ? _a : [],
|
|
383
|
-
userData: '{}',
|
|
384
|
-
retries: step.retries || 0,
|
|
385
|
-
rateLimits: (0, step_1.mapRateLimit)(step.rate_limits),
|
|
386
|
-
workerLabels: toPbWorkerLabel(step.worker_labels),
|
|
387
|
-
backoffFactor: (_b = step.backoff) === null || _b === void 0 ? void 0 : _b.factor,
|
|
388
|
-
backoffMaxSeconds: (_c = step.backoff) === null || _c === void 0 ? void 0 : _c.maxSeconds,
|
|
389
|
-
});
|
|
390
|
-
}),
|
|
391
|
-
},
|
|
392
|
-
],
|
|
294
|
+
}))) !== null && _v !== void 0 ? _v : [],
|
|
393
295
|
});
|
|
394
296
|
this.registeredWorkflowPromises.push(registeredWorkflow);
|
|
395
297
|
yield registeredWorkflow;
|
|
@@ -401,12 +303,9 @@ class V1Worker {
|
|
|
401
303
|
this.registerActions(workflow);
|
|
402
304
|
});
|
|
403
305
|
}
|
|
404
|
-
registerAction(actionId, action) {
|
|
405
|
-
this.action_registry[actionId.toLowerCase()] = action;
|
|
406
|
-
}
|
|
407
306
|
handleStartStepRun(action) {
|
|
408
307
|
return __awaiter(this, void 0, void 0, function* () {
|
|
409
|
-
const { actionId, taskRunExternalId } = action;
|
|
308
|
+
const { actionId, taskRunExternalId, taskName } = action;
|
|
410
309
|
try {
|
|
411
310
|
// Note: we always use a DurableContext since its a superset of the Context class
|
|
412
311
|
const context = new context_1.DurableContext(action, this.client, this);
|
|
@@ -418,32 +317,37 @@ class V1Worker {
|
|
|
418
317
|
return;
|
|
419
318
|
}
|
|
420
319
|
const run = () => __awaiter(this, void 0, void 0, function* () {
|
|
421
|
-
parent_run_context_vars_1.parentRunContextManager.setContext({
|
|
422
|
-
parentId: action.workflowRunId,
|
|
423
|
-
parentTaskRunExternalId: taskRunExternalId,
|
|
424
|
-
childIndex: 0,
|
|
425
|
-
desiredWorkerId: this.workerId || '',
|
|
426
|
-
});
|
|
427
320
|
const { middleware } = this.client.config;
|
|
428
321
|
if (middleware === null || middleware === void 0 ? void 0 : middleware.before) {
|
|
429
322
|
const hooks = Array.isArray(middleware.before) ? middleware.before : [middleware.before];
|
|
430
323
|
for (const hook of hooks) {
|
|
431
|
-
const
|
|
432
|
-
if (
|
|
433
|
-
context.input
|
|
324
|
+
const extra = yield hook(context.input, context);
|
|
325
|
+
if (extra !== undefined) {
|
|
326
|
+
const merged = Object.assign(Object.assign({}, context.input), extra);
|
|
327
|
+
context.input = merged;
|
|
434
328
|
if (context.data && typeof context.data === 'object') {
|
|
435
|
-
context.data.input =
|
|
329
|
+
context.data.input = merged;
|
|
436
330
|
}
|
|
437
331
|
}
|
|
438
332
|
}
|
|
439
333
|
}
|
|
440
|
-
let result = yield
|
|
334
|
+
let result = yield parent_run_context_vars_1.parentRunContextManager.runWithContext({
|
|
335
|
+
parentId: action.workflowRunId,
|
|
336
|
+
parentTaskRunExternalId: taskRunExternalId,
|
|
337
|
+
childIndex: 0,
|
|
338
|
+
desiredWorkerId: this.workerId || '',
|
|
339
|
+
signal: context.abortController.signal,
|
|
340
|
+
}, () => {
|
|
341
|
+
// Precheck: if cancellation already happened, don't execute user code.
|
|
342
|
+
(0, abort_error_1.throwIfAborted)(context.abortController.signal);
|
|
343
|
+
return step(context);
|
|
344
|
+
});
|
|
441
345
|
if (middleware === null || middleware === void 0 ? void 0 : middleware.after) {
|
|
442
346
|
const hooks = Array.isArray(middleware.after) ? middleware.after : [middleware.after];
|
|
443
347
|
for (const hook of hooks) {
|
|
444
|
-
const
|
|
445
|
-
if (
|
|
446
|
-
result =
|
|
348
|
+
const extra = yield hook(result, context, context.input);
|
|
349
|
+
if (extra !== undefined) {
|
|
350
|
+
result = extra;
|
|
447
351
|
}
|
|
448
352
|
}
|
|
449
353
|
}
|
|
@@ -454,17 +358,17 @@ class V1Worker {
|
|
|
454
358
|
if (context.cancelled) {
|
|
455
359
|
return;
|
|
456
360
|
}
|
|
457
|
-
this.logger.info(
|
|
361
|
+
this.logger.info((0, logger_1.taskRunLog)(taskName, taskRunExternalId, 'completed'));
|
|
458
362
|
// Send the action event to the dispatcher
|
|
459
363
|
const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_COMPLETED, false, result || null, action.retryCount);
|
|
460
|
-
yield this.client.
|
|
364
|
+
yield this.client.dispatcher.sendStepActionEvent(event);
|
|
461
365
|
}
|
|
462
366
|
catch (actionEventError) {
|
|
463
367
|
this.logger.error(`Could not send completed action event: ${actionEventError.message || actionEventError}`);
|
|
464
368
|
// send a failure event
|
|
465
369
|
const failureEvent = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_FAILED, false, actionEventError.message, action.retryCount);
|
|
466
370
|
try {
|
|
467
|
-
yield this.client.
|
|
371
|
+
yield this.client.dispatcher.sendStepActionEvent(failureEvent);
|
|
468
372
|
}
|
|
469
373
|
catch (failureEventError) {
|
|
470
374
|
this.logger.error(`Could not send failed action event: ${failureEventError.message || failureEventError}`);
|
|
@@ -483,7 +387,7 @@ class V1Worker {
|
|
|
483
387
|
if (context.cancelled) {
|
|
484
388
|
return;
|
|
485
389
|
}
|
|
486
|
-
this.logger.error(
|
|
390
|
+
this.logger.error((0, logger_1.taskRunLog)(taskName, taskRunExternalId, `failed: ${error.message}`));
|
|
487
391
|
if (error.stack) {
|
|
488
392
|
this.logger.error(error.stack);
|
|
489
393
|
}
|
|
@@ -492,7 +396,7 @@ class V1Worker {
|
|
|
492
396
|
message: error === null || error === void 0 ? void 0 : error.message,
|
|
493
397
|
stack: error === null || error === void 0 ? void 0 : error.stack,
|
|
494
398
|
}, action.retryCount);
|
|
495
|
-
yield this.client.
|
|
399
|
+
yield this.client.dispatcher.sendStepActionEvent(event);
|
|
496
400
|
}
|
|
497
401
|
catch (e) {
|
|
498
402
|
this.logger.error(`Could not send action event: ${e.message}`);
|
|
@@ -512,12 +416,21 @@ class V1Worker {
|
|
|
512
416
|
yield failure(e);
|
|
513
417
|
return;
|
|
514
418
|
}
|
|
419
|
+
// Postcheck: user code may swallow AbortError; don't report completion after cancellation.
|
|
420
|
+
// If we reached this point and the signal is aborted, the task likely caught/ignored cancellation.
|
|
421
|
+
if (context.abortController.signal.aborted) {
|
|
422
|
+
this.logger.warn(`Cancellation: task run ${taskRunExternalId} returned after cancellation was signaled. ` +
|
|
423
|
+
`This usually means an AbortError was caught and not propagated. ` +
|
|
424
|
+
`See https://docs.hatchet.run/home/cancellation`);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
(0, abort_error_1.throwIfAborted)(context.abortController.signal);
|
|
515
428
|
yield success(result);
|
|
516
429
|
}))());
|
|
517
430
|
this.futures[taskRunExternalId] = future;
|
|
518
431
|
// Send the action event to the dispatcher
|
|
519
432
|
const event = this.getStepActionEvent(action, dispatcher_1.StepActionEventType.STEP_EVENT_TYPE_STARTED, false, undefined, action.retryCount);
|
|
520
|
-
this.client.
|
|
433
|
+
this.client.dispatcher.sendStepActionEvent(event).catch((e) => {
|
|
521
434
|
this.logger.error(`Could not send action event: ${e.message}`);
|
|
522
435
|
});
|
|
523
436
|
try {
|
|
@@ -525,10 +438,8 @@ class V1Worker {
|
|
|
525
438
|
}
|
|
526
439
|
catch (e) {
|
|
527
440
|
const message = (e === null || e === void 0 ? void 0 : e.message) || String(e);
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
else {
|
|
441
|
+
// TODO is this cased correctly...
|
|
442
|
+
if (!message.includes('Cancelled')) {
|
|
532
443
|
this.logger.error(`Could not wait for task run ${taskRunExternalId} to finish. ` +
|
|
533
444
|
`See https://docs.hatchet.run/home/cancellation for best practices on handling cancellation: `, e);
|
|
534
445
|
}
|
|
@@ -541,7 +452,7 @@ class V1Worker {
|
|
|
541
452
|
}
|
|
542
453
|
handleStartGroupKeyRun(action) {
|
|
543
454
|
return __awaiter(this, void 0, void 0, function* () {
|
|
544
|
-
const { actionId, getGroupKeyRunId, taskRunExternalId } = action;
|
|
455
|
+
const { actionId, getGroupKeyRunId, taskRunExternalId, taskName } = action;
|
|
545
456
|
this.logger.error('Concurrency Key Functions have been deprecated and will be removed in a future release. Use Concurrency Expressions instead.');
|
|
546
457
|
try {
|
|
547
458
|
const context = new context_1.Context(action, this.client, this);
|
|
@@ -561,11 +472,11 @@ class V1Worker {
|
|
|
561
472
|
return step(context);
|
|
562
473
|
});
|
|
563
474
|
const success = (result) => {
|
|
564
|
-
this.logger.info(
|
|
475
|
+
this.logger.info((0, logger_1.taskRunLog)(taskName, taskRunExternalId, 'completed'));
|
|
565
476
|
try {
|
|
566
477
|
// Send the action event to the dispatcher
|
|
567
478
|
const event = this.getGroupKeyActionEvent(action, dispatcher_1.GroupKeyActionEventType.GROUP_KEY_EVENT_TYPE_COMPLETED, result);
|
|
568
|
-
this.client.
|
|
479
|
+
this.client.dispatcher.sendGroupKeyActionEvent(event).catch((e) => {
|
|
569
480
|
this.logger.error(`Could not send action event: ${e.message}`);
|
|
570
481
|
});
|
|
571
482
|
}
|
|
@@ -579,11 +490,11 @@ class V1Worker {
|
|
|
579
490
|
}
|
|
580
491
|
};
|
|
581
492
|
const failure = (error) => {
|
|
582
|
-
this.logger.error(
|
|
493
|
+
this.logger.error((0, logger_1.taskRunLog)(taskName, taskRunExternalId, `failed: ${error.message}`));
|
|
583
494
|
try {
|
|
584
495
|
// Send the action event to the dispatcher
|
|
585
496
|
const event = this.getGroupKeyActionEvent(action, dispatcher_1.GroupKeyActionEventType.GROUP_KEY_EVENT_TYPE_FAILED, error);
|
|
586
|
-
this.client.
|
|
497
|
+
this.client.dispatcher.sendGroupKeyActionEvent(event).catch((e) => {
|
|
587
498
|
this.logger.error(`Could not send action event: ${e.message}`);
|
|
588
499
|
});
|
|
589
500
|
}
|
|
@@ -600,7 +511,7 @@ class V1Worker {
|
|
|
600
511
|
this.futures[key] = future;
|
|
601
512
|
// Send the action event to the dispatcher
|
|
602
513
|
const event = this.getGroupKeyActionEvent(action, dispatcher_1.GroupKeyActionEventType.GROUP_KEY_EVENT_TYPE_STARTED);
|
|
603
|
-
this.client.
|
|
514
|
+
this.client.dispatcher.sendGroupKeyActionEvent(event).catch((e) => {
|
|
604
515
|
this.logger.error(`Could not send action event: ${e.message}`);
|
|
605
516
|
});
|
|
606
517
|
yield future.promise;
|
|
@@ -641,25 +552,60 @@ class V1Worker {
|
|
|
641
552
|
}
|
|
642
553
|
handleCancelStepRun(action) {
|
|
643
554
|
return __awaiter(this, void 0, void 0, function* () {
|
|
644
|
-
|
|
555
|
+
var _a, _b, _c;
|
|
556
|
+
const { taskRunExternalId, taskName } = action;
|
|
645
557
|
try {
|
|
646
|
-
this.logger.info(`Cancelling task run ${taskRunExternalId}`);
|
|
647
558
|
const future = this.futures[taskRunExternalId];
|
|
648
559
|
const context = this.contexts[taskRunExternalId];
|
|
649
560
|
if (context && context.abortController) {
|
|
650
|
-
context.abortController.abort('Cancelled by worker');
|
|
561
|
+
context.abortController.abort('Cancelled by worker'); // TODO this reason is nonsensical
|
|
651
562
|
}
|
|
652
563
|
if (future) {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
564
|
+
const start = Date.now();
|
|
565
|
+
const warningThresholdMs = (_a = this.client.config.cancellation_warning_threshold) !== null && _a !== void 0 ? _a : 300;
|
|
566
|
+
const gracePeriodMs = (_b = this.client.config.cancellation_grace_period) !== null && _b !== void 0 ? _b : 1000;
|
|
567
|
+
const warningMs = Math.max(0, warningThresholdMs);
|
|
568
|
+
const graceMs = Math.max(0, gracePeriodMs);
|
|
569
|
+
// Ensure cancelling this future doesn't create an unhandled rejection in cases
|
|
570
|
+
// where the main action handler isn't currently awaiting `future.promise`.
|
|
571
|
+
future.promise.catch(() => undefined);
|
|
572
|
+
// Cancel the future (rejects the wrapper); user code must still cooperate with AbortSignal.
|
|
573
|
+
future.cancel('Cancelled by worker'); // TODO this reason is nonsensical
|
|
574
|
+
// Track completion of the underlying work (not the cancelable wrapper).
|
|
575
|
+
// Ensure this promise never throws into our supervision flow.
|
|
576
|
+
const completion = ((_c = future.inner) !== null && _c !== void 0 ? _c : future.promise).catch(() => undefined);
|
|
577
|
+
// Wait until warning threshold, then log if still running.
|
|
578
|
+
if (warningMs > 0) {
|
|
579
|
+
const winner = yield Promise.race([
|
|
580
|
+
completion.then(() => 'done'),
|
|
581
|
+
(0, sleep_1.default)(warningMs).then(() => 'warn'),
|
|
582
|
+
]);
|
|
583
|
+
if (winner === 'warn') {
|
|
584
|
+
const milliseconds = Date.now() - start;
|
|
585
|
+
this.logger.warn(`Cancellation: task run ${taskRunExternalId} has not cancelled after ${milliseconds}ms. Consider checking for blocking operations. ` +
|
|
586
|
+
`See https://docs.hatchet.run/home/cancellation`);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
// Wait until grace period (total), then log if still running.
|
|
590
|
+
const elapsedMs = Date.now() - start;
|
|
591
|
+
const remainingMs = graceMs - elapsedMs;
|
|
592
|
+
const winner = yield Promise.race([
|
|
593
|
+
completion.then(() => 'done'),
|
|
594
|
+
(0, sleep_1.default)(Math.max(0, remainingMs)).then(() => 'grace'),
|
|
595
|
+
]);
|
|
596
|
+
if (winner === 'done') {
|
|
597
|
+
this.logger.info((0, logger_1.taskRunLog)(taskName, taskRunExternalId, 'cancelled'));
|
|
598
|
+
}
|
|
599
|
+
else {
|
|
600
|
+
const totalElapsedMs = Date.now() - start;
|
|
601
|
+
this.logger.error(`Cancellation: task run ${taskRunExternalId} still running after cancellation grace period ` +
|
|
602
|
+
`${totalElapsedMs}ms.\n` +
|
|
603
|
+
`JavaScript cannot force-kill user code; see: https://docs.hatchet.run/home/cancellation`);
|
|
604
|
+
}
|
|
658
605
|
}
|
|
659
606
|
}
|
|
660
607
|
catch (e) {
|
|
661
|
-
|
|
662
|
-
this.logger.debug(`Task run ${taskRunExternalId} cancellation completed`);
|
|
608
|
+
this.logger.error(`Cancellation: error while supervising cancellation for task run ${taskRunExternalId}: ${(e === null || e === void 0 ? void 0 : e.message) || e}`);
|
|
663
609
|
}
|
|
664
610
|
finally {
|
|
665
611
|
delete this.futures[taskRunExternalId];
|
|
@@ -708,7 +654,7 @@ class V1Worker {
|
|
|
708
654
|
*/
|
|
709
655
|
createListener() {
|
|
710
656
|
return __awaiter(this, void 0, void 0, function* () {
|
|
711
|
-
return this.client.
|
|
657
|
+
return this.client.dispatcher.getActionListener({
|
|
712
658
|
workerName: this.name,
|
|
713
659
|
services: ['default'],
|
|
714
660
|
actions: Object.keys(this.action_registry),
|
|
@@ -747,7 +693,8 @@ class V1Worker {
|
|
|
747
693
|
_c = generator_1_1.value;
|
|
748
694
|
_d = false;
|
|
749
695
|
const action = _c;
|
|
750
|
-
|
|
696
|
+
const receivedType = (0, logger_1.actionMap)(action.actionType);
|
|
697
|
+
this.logger.info((0, logger_1.taskRunLog)(action.taskName, action.taskRunExternalId, `${receivedType}`));
|
|
751
698
|
void this.handleAction(action);
|
|
752
699
|
}
|
|
753
700
|
}
|
|
@@ -796,41 +743,41 @@ class V1Worker {
|
|
|
796
743
|
this.logger.warn('Worker not registered.');
|
|
797
744
|
return this.labels;
|
|
798
745
|
}
|
|
799
|
-
this.client.
|
|
746
|
+
this.client.dispatcher.upsertWorkerLabels(this.workerId, labels);
|
|
800
747
|
return this.labels;
|
|
801
748
|
});
|
|
802
749
|
}
|
|
803
750
|
}
|
|
804
|
-
exports.
|
|
805
|
-
function
|
|
751
|
+
exports.InternalWorker = InternalWorker;
|
|
752
|
+
function mapWorkerLabelPb(in_) {
|
|
806
753
|
if (!in_) {
|
|
807
754
|
return {};
|
|
808
755
|
}
|
|
809
|
-
return Object.entries(in_).reduce((acc, [key,
|
|
810
|
-
if (!
|
|
756
|
+
return Object.entries(in_).reduce((acc, [key, label]) => {
|
|
757
|
+
if (!label) {
|
|
811
758
|
return Object.assign(Object.assign({}, acc), { [key]: {
|
|
812
759
|
strValue: undefined,
|
|
813
760
|
intValue: undefined,
|
|
814
761
|
} });
|
|
815
762
|
}
|
|
816
|
-
if (typeof
|
|
763
|
+
if (typeof label === 'string') {
|
|
817
764
|
return Object.assign(Object.assign({}, acc), { [key]: {
|
|
818
|
-
strValue:
|
|
765
|
+
strValue: label,
|
|
819
766
|
intValue: undefined,
|
|
820
767
|
} });
|
|
821
768
|
}
|
|
822
|
-
if (typeof
|
|
769
|
+
if (typeof label === 'number') {
|
|
823
770
|
return Object.assign(Object.assign({}, acc), { [key]: {
|
|
824
771
|
strValue: undefined,
|
|
825
|
-
intValue:
|
|
772
|
+
intValue: label,
|
|
826
773
|
} });
|
|
827
774
|
}
|
|
828
775
|
return Object.assign(Object.assign({}, acc), { [key]: {
|
|
829
|
-
strValue: typeof
|
|
830
|
-
intValue: typeof
|
|
831
|
-
required:
|
|
832
|
-
weight:
|
|
833
|
-
comparator:
|
|
776
|
+
strValue: typeof label.value === 'string' ? label.value : undefined,
|
|
777
|
+
intValue: typeof label.value === 'number' ? label.value : undefined,
|
|
778
|
+
required: label.required,
|
|
779
|
+
weight: label.weight,
|
|
780
|
+
comparator: label.comparator,
|
|
834
781
|
} });
|
|
835
782
|
}, {});
|
|
836
783
|
}
|
|
@@ -843,3 +790,72 @@ function getLeaves(tasks) {
|
|
|
843
790
|
function isLeafTask(task, allTasks) {
|
|
844
791
|
return !allTasks.some((t) => { var _a; return (_a = t.parents) === null || _a === void 0 ? void 0 : _a.some((p) => p.name === task.name); });
|
|
845
792
|
}
|
|
793
|
+
function mapRateLimitPb(limits) {
|
|
794
|
+
if (!limits)
|
|
795
|
+
return [];
|
|
796
|
+
return limits.map((l) => {
|
|
797
|
+
let key = l.staticKey;
|
|
798
|
+
const keyExpression = l.dynamicKey;
|
|
799
|
+
if (l.key !== undefined) {
|
|
800
|
+
// eslint-disable-next-line no-console
|
|
801
|
+
console.warn('key is deprecated and will be removed in a future release, please use staticKey instead');
|
|
802
|
+
key = l.key;
|
|
803
|
+
}
|
|
804
|
+
if (keyExpression !== undefined) {
|
|
805
|
+
if (key !== undefined) {
|
|
806
|
+
throw new Error('Cannot have both static key and dynamic key set');
|
|
807
|
+
}
|
|
808
|
+
key = keyExpression;
|
|
809
|
+
if (!validateCelExpression(keyExpression)) {
|
|
810
|
+
throw new Error(`Invalid CEL expression: ${keyExpression}`);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
if (key === undefined) {
|
|
814
|
+
throw new Error(`Invalid key`);
|
|
815
|
+
}
|
|
816
|
+
let units;
|
|
817
|
+
let unitsExpression;
|
|
818
|
+
if (typeof l.units === 'number') {
|
|
819
|
+
units = l.units;
|
|
820
|
+
}
|
|
821
|
+
else {
|
|
822
|
+
if (!validateCelExpression(l.units)) {
|
|
823
|
+
throw new Error(`Invalid CEL expression: ${l.units}`);
|
|
824
|
+
}
|
|
825
|
+
unitsExpression = l.units;
|
|
826
|
+
}
|
|
827
|
+
let limitExpression;
|
|
828
|
+
if (l.limit !== undefined) {
|
|
829
|
+
if (typeof l.limit === 'number') {
|
|
830
|
+
limitExpression = `${l.limit}`;
|
|
831
|
+
}
|
|
832
|
+
else {
|
|
833
|
+
if (!validateCelExpression(l.limit)) {
|
|
834
|
+
throw new Error(`Invalid CEL expression: ${l.limit}`);
|
|
835
|
+
}
|
|
836
|
+
limitExpression = l.limit;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
if (keyExpression !== undefined && limitExpression === undefined) {
|
|
840
|
+
throw new Error('CEL based keys requires limit to be set');
|
|
841
|
+
}
|
|
842
|
+
if (limitExpression === undefined) {
|
|
843
|
+
limitExpression = `-1`;
|
|
844
|
+
}
|
|
845
|
+
return {
|
|
846
|
+
key,
|
|
847
|
+
keyExpr: keyExpression,
|
|
848
|
+
units,
|
|
849
|
+
unitsExpr: unitsExpression,
|
|
850
|
+
limitValuesExpr: limitExpression,
|
|
851
|
+
duration: l.duration,
|
|
852
|
+
};
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
// Helper function to validate CEL expressions
|
|
856
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
857
|
+
function validateCelExpression(_expr) {
|
|
858
|
+
// FIXME: this is a placeholder. In a real implementation, you'd need to use a CEL parser or validator.
|
|
859
|
+
// For now, we'll just return true to mimic the behavior.
|
|
860
|
+
return true;
|
|
861
|
+
}
|