@hatchet-dev/typescript-sdk 1.16.0 → 1.17.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/README.md +14 -2
- package/clients/admin/admin-client.d.ts +2 -2
- package/clients/dispatcher/action-listener.d.ts +3 -6
- package/clients/dispatcher/action-listener.js +12 -17
- package/clients/listeners/durable-listener/durable-listener-client.d.ts +116 -15
- package/clients/listeners/durable-listener/durable-listener-client.js +770 -19
- package/clients/listeners/durable-listener/pooled-durable-listener-client.js +1 -14
- package/clients/listeners/run-listener/pooled-child-listener-client.js +1 -14
- package/clients/rest/generated/Api.d.ts +5 -1
- package/clients/rest/generated/data-contracts.d.ts +16 -2
- package/clients/rest/generated/data-contracts.js +7 -3
- package/legacy/examples/affinity-workers.js +2 -2
- package/legacy/legacy-client.js +1 -1
- package/legacy/step.d.ts +2 -2
- package/legacy/step.js +3 -2
- package/legacy/workflow.d.ts +25 -25
- package/package.json +1 -1
- package/protoc/dispatcher/dispatcher.d.ts +20 -0
- package/protoc/dispatcher/dispatcher.js +535 -100
- package/protoc/events/events.js +54 -14
- package/protoc/google/protobuf/timestamp.js +1 -1
- package/protoc/v1/dispatcher.d.ts +169 -0
- package/protoc/v1/dispatcher.js +2096 -8
- package/protoc/v1/shared/condition.js +37 -11
- package/protoc/v1/shared/trigger.d.ts +89 -0
- package/protoc/v1/shared/trigger.js +524 -0
- package/protoc/v1/workflows.d.ts +34 -34
- package/protoc/v1/workflows.js +452 -254
- package/protoc/workflows/workflows.d.ts +2 -75
- package/protoc/workflows/workflows.js +157 -529
- package/util/abort-error.d.ts +10 -0
- package/util/abort-error.js +15 -0
- package/util/errors/eviction-not-supported-error.d.ts +5 -0
- package/util/errors/eviction-not-supported-error.js +18 -0
- package/util/errors/non-determinism-error.d.ts +7 -0
- package/util/errors/non-determinism-error.js +21 -0
- package/util/errors/task-run-terminated-error.d.ts +6 -0
- package/util/errors/task-run-terminated-error.js +15 -0
- package/util/hatchet-promise/hatchet-promise.d.ts +2 -1
- package/util/hatchet-promise/hatchet-promise.js +10 -1
- package/util/sleep.d.ts +3 -2
- package/util/sleep.js +6 -4
- package/v1/client/admin.d.ts +2 -2
- package/v1/client/client.js +1 -1
- package/v1/client/duration.d.ts +11 -1
- package/v1/client/duration.js +44 -0
- package/v1/client/features/runs.d.ts +16 -3
- package/v1/client/features/runs.js +38 -3
- package/v1/client/worker/context.d.ts +101 -6
- package/v1/client/worker/context.js +247 -21
- package/v1/client/worker/deprecated/index.d.ts +1 -1
- package/v1/client/worker/deprecated/index.js +2 -1
- package/v1/client/worker/deprecated/legacy-worker.d.ts +5 -0
- package/v1/client/worker/deprecated/legacy-worker.js +32 -23
- package/v1/client/worker/deprecated/pre-eviction.d.ts +12 -0
- package/v1/client/worker/deprecated/pre-eviction.js +37 -0
- package/v1/client/worker/engine-version.d.ts +5 -0
- package/v1/client/worker/engine-version.js +14 -0
- package/v1/client/worker/eviction/eviction-cache.d.ts +33 -0
- package/v1/client/worker/eviction/eviction-cache.js +139 -0
- package/v1/client/worker/eviction/eviction-manager.d.ts +42 -0
- package/v1/client/worker/eviction/eviction-manager.js +132 -0
- package/v1/client/worker/eviction/eviction-policy.d.ts +19 -0
- package/v1/client/worker/eviction/eviction-policy.js +8 -0
- package/v1/client/worker/eviction/index.d.ts +3 -0
- package/v1/client/worker/eviction/index.js +11 -0
- package/v1/client/worker/worker-internal.d.ts +23 -4
- package/v1/client/worker/worker-internal.js +177 -138
- package/v1/client/worker/worker.d.ts +1 -0
- package/v1/client/worker/worker.js +34 -1
- package/v1/conditions/sleep-condition.js +2 -1
- package/v1/conditions/transformer.js +2 -1
- package/v1/declaration.d.ts +5 -3
- package/v1/declaration.js +8 -0
- package/v1/examples/__e2e__/harness.d.ts +5 -0
- package/v1/examples/__e2e__/harness.js +13 -0
- package/v1/examples/concurrency_workflow_level/workflow.d.ts +1 -1
- package/v1/examples/concurrency_workflow_level/workflow.js +1 -1
- package/v1/examples/durable/workflow.d.ts +57 -0
- package/v1/examples/durable/workflow.js +162 -7
- package/v1/examples/durable-event/workflow.js +2 -7
- package/v1/examples/durable_event/workflow.d.ts +1 -0
- package/v1/examples/durable_event/workflow.js +4 -9
- package/v1/examples/durable_eviction/capacity-worker.d.ts +1 -0
- package/v1/examples/durable_eviction/capacity-worker.js +31 -0
- package/v1/examples/durable_eviction/worker.d.ts +1 -0
- package/v1/examples/durable_eviction/worker.js +34 -0
- package/v1/examples/durable_eviction/workflow.d.ts +44 -0
- package/v1/examples/durable_eviction/workflow.js +129 -0
- package/v1/examples/e2e-worker.js +42 -19
- package/v1/index.d.ts +5 -0
- package/v1/index.js +10 -0
- package/v1/parent-run-context-vars.d.ts +6 -0
- package/v1/task.d.ts +10 -2
- package/v1/task.js +2 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
package/v1/declaration.d.ts
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
import WorkflowRunRef from '../util/workflow-run-ref';
|
|
9
9
|
import { CronWorkflows, ScheduledWorkflows, V1CreateFilterRequest } from '../clients/rest/generated/data-contracts';
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import { WorkerLabelComparator } from '../protoc/v1/workflows';
|
|
12
11
|
import { IHatchetClient } from './client/client.interface';
|
|
13
|
-
import { CreateWorkflowTaskOpts, CreateOnFailureTaskOpts, TaskFn, CreateWorkflowDurableTaskOpts, CreateBaseTaskOpts, CreateOnSuccessTaskOpts, Concurrency, DurableTaskFn } from './task';
|
|
12
|
+
import { CreateWorkflowTaskOpts, CreateOnFailureTaskOpts, TaskFn, CreateWorkflowDurableTaskOpts, CreateBaseTaskOpts, CreateOnSuccessTaskOpts, Concurrency, DurableTaskFn, WorkerLabelComparator } from './task';
|
|
14
13
|
import { Duration } from './client/duration';
|
|
15
14
|
import { MetricsClient } from './client/features/metrics';
|
|
16
15
|
import { InputType, OutputType, UnknownInputType, JsonObject, Resolved } from './types';
|
|
17
16
|
import { Context, DurableContext } from './client/worker/context';
|
|
17
|
+
import { EvictionPolicy } from './client/worker/eviction/eviction-policy';
|
|
18
18
|
export declare enum Priority {
|
|
19
19
|
LOW = 1,
|
|
20
20
|
MEDIUM = 2,
|
|
@@ -141,7 +141,9 @@ export type CreateBaseWorkflowOpts = {
|
|
|
141
141
|
inputValidator?: z.ZodType<any>;
|
|
142
142
|
};
|
|
143
143
|
export type CreateTaskWorkflowOpts<I extends InputType = UnknownInputType, O extends OutputType = void> = CreateBaseWorkflowOpts & CreateBaseTaskOpts<I, O, TaskFn<I, O>>;
|
|
144
|
-
export type CreateDurableTaskWorkflowOpts<I extends InputType = UnknownInputType, O extends OutputType = void> = CreateBaseWorkflowOpts & CreateBaseTaskOpts<I, O, DurableTaskFn<I, O
|
|
144
|
+
export type CreateDurableTaskWorkflowOpts<I extends InputType = UnknownInputType, O extends OutputType = void> = CreateBaseWorkflowOpts & CreateBaseTaskOpts<I, O, DurableTaskFn<I, O>> & {
|
|
145
|
+
evictionPolicy?: EvictionPolicy;
|
|
146
|
+
};
|
|
145
147
|
/**
|
|
146
148
|
* Options for creating a new workflow.
|
|
147
149
|
* @hidden
|
package/v1/declaration.js
CHANGED
|
@@ -131,9 +131,17 @@ class BaseWorkflowDeclaration {
|
|
|
131
131
|
}
|
|
132
132
|
run(input, options, _standaloneTaskName) {
|
|
133
133
|
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
+
var _a;
|
|
134
135
|
if (!this.client) {
|
|
135
136
|
throw UNBOUND_ERR;
|
|
136
137
|
}
|
|
138
|
+
const durableCtx = (_a = parent_run_context_vars_1.parentRunContextManager.getContext()) === null || _a === void 0 ? void 0 : _a.durableContext;
|
|
139
|
+
if (durableCtx) {
|
|
140
|
+
if (Array.isArray(input)) {
|
|
141
|
+
return durableCtx.spawnChildren(input.map((inp) => ({ workflow: this, input: inp, options })));
|
|
142
|
+
}
|
|
143
|
+
return durableCtx.spawnChild(this, input, options);
|
|
144
|
+
}
|
|
137
145
|
if (Array.isArray(input)) {
|
|
138
146
|
const refs = yield this.runNoWait(input, options, _standaloneTaskName);
|
|
139
147
|
if (options === null || options === void 0 ? void 0 : options.returnExceptions) {
|
|
@@ -11,6 +11,11 @@ export declare function startWorker({ client, name, workflows, slots, }: {
|
|
|
11
11
|
slots?: number;
|
|
12
12
|
}): Promise<Worker>;
|
|
13
13
|
export declare function stopWorker(worker: Worker | undefined): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Checks whether the connected engine supports durable eviction.
|
|
16
|
+
* Call from beforeAll / beforeEach and skip tests when false.
|
|
17
|
+
*/
|
|
18
|
+
export declare function checkDurableEvictionSupport(client: HatchetClient): Promise<boolean>;
|
|
14
19
|
export declare function poll<T>(fn: () => Promise<T>, { timeoutMs, intervalMs, shouldStop, label, }: {
|
|
15
20
|
timeoutMs?: number;
|
|
16
21
|
intervalMs?: number;
|
|
@@ -17,10 +17,13 @@ exports.makeE2EClient = makeE2EClient;
|
|
|
17
17
|
exports.makeTestScope = makeTestScope;
|
|
18
18
|
exports.startWorker = startWorker;
|
|
19
19
|
exports.stopWorker = stopWorker;
|
|
20
|
+
exports.checkDurableEvictionSupport = checkDurableEvictionSupport;
|
|
20
21
|
exports.poll = poll;
|
|
21
22
|
const sleep_1 = __importDefault(require("../../../util/sleep"));
|
|
22
23
|
const crypto_1 = require("crypto");
|
|
23
24
|
const v1_1 = require("../..");
|
|
25
|
+
const engine_version_1 = require("../../client/worker/engine-version");
|
|
26
|
+
const legacy_worker_1 = require("../../client/worker/deprecated/legacy-worker");
|
|
24
27
|
function requireEnv(name) {
|
|
25
28
|
const value = process.env[name];
|
|
26
29
|
if (!value) {
|
|
@@ -54,6 +57,16 @@ function stopWorker(worker) {
|
|
|
54
57
|
yield (0, sleep_1.default)(300);
|
|
55
58
|
});
|
|
56
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Checks whether the connected engine supports durable eviction.
|
|
62
|
+
* Call from beforeAll / beforeEach and skip tests when false.
|
|
63
|
+
*/
|
|
64
|
+
function checkDurableEvictionSupport(client) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const version = yield (0, legacy_worker_1.fetchEngineVersion)(client).catch(() => undefined);
|
|
67
|
+
return (0, engine_version_1.supportsEviction)(version);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
57
70
|
function poll(fn_1, _a) {
|
|
58
71
|
return __awaiter(this, arguments, void 0, function* (fn, { timeoutMs = 30000, intervalMs = 100, shouldStop, label = 'poll', }) {
|
|
59
72
|
const start = Date.now();
|
|
@@ -15,7 +15,7 @@ const hatchet_client_1 = require("../hatchet-client");
|
|
|
15
15
|
const sleep = (ms) => new Promise((resolve) => {
|
|
16
16
|
setTimeout(resolve, ms);
|
|
17
17
|
});
|
|
18
|
-
exports.SLEEP_TIME_MS =
|
|
18
|
+
exports.SLEEP_TIME_MS = 2000;
|
|
19
19
|
exports.DIGIT_MAX_RUNS = 8;
|
|
20
20
|
exports.NAME_MAX_RUNS = 3;
|
|
21
21
|
exports.concurrencyWorkflowLevelWorkflow = hatchet_client_1.hatchet.workflow({
|
|
@@ -5,3 +5,60 @@ export declare const durableWorkflow: import("../..").WorkflowDeclaration<import
|
|
|
5
5
|
export declare const waitForSleepTwice: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
6
6
|
runtime: number;
|
|
7
7
|
}, {}, {}, {}, {}>;
|
|
8
|
+
export declare const spawnChildTask: import("../..").TaskWorkflowDeclaration<{
|
|
9
|
+
n?: number;
|
|
10
|
+
}, {
|
|
11
|
+
message: string;
|
|
12
|
+
}, {}, {}, {}, {}>;
|
|
13
|
+
export declare const durableWithSpawn: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
14
|
+
child_output: {
|
|
15
|
+
message: string;
|
|
16
|
+
};
|
|
17
|
+
}, {}, {}, {}, {}>;
|
|
18
|
+
export declare const durableWithBulkSpawn: import("../..").TaskWorkflowDeclaration<{
|
|
19
|
+
n?: number;
|
|
20
|
+
}, {
|
|
21
|
+
child_outputs: {
|
|
22
|
+
message: string;
|
|
23
|
+
}[];
|
|
24
|
+
}, {}, {}, {}, {}>;
|
|
25
|
+
export declare const durableSleepEventSpawn: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
26
|
+
runtime: number;
|
|
27
|
+
child_output: {
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
}, {}, {}, {}, {}>;
|
|
31
|
+
export declare const durableWithExplicitSpawn: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
32
|
+
child_output: {
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
35
|
+
}, {}, {}, {}, {}>;
|
|
36
|
+
export declare const durableNonDeterminism: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
37
|
+
attempt_number: number;
|
|
38
|
+
sleep_time: number;
|
|
39
|
+
non_determinism_detected: true;
|
|
40
|
+
node_id: number;
|
|
41
|
+
} | {
|
|
42
|
+
attempt_number: number;
|
|
43
|
+
sleep_time: number;
|
|
44
|
+
non_determinism_detected: false;
|
|
45
|
+
node_id?: undefined;
|
|
46
|
+
}, {}, {}, {}, {}>;
|
|
47
|
+
export declare const REPLAY_RESET_SLEEP_SECONDS = 3;
|
|
48
|
+
/** Max duration (seconds) for a replayed/memoized step; above this we treat it as a real sleep. */
|
|
49
|
+
export declare const REPLAY_RESET_MEMOIZED_MAX_SECONDS = 5;
|
|
50
|
+
export declare const durableReplayReset: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
51
|
+
sleep_1_duration: number;
|
|
52
|
+
sleep_2_duration: number;
|
|
53
|
+
sleep_3_duration: number;
|
|
54
|
+
}, {}, {}, {}, {}>;
|
|
55
|
+
export declare const memoNowCaching: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
56
|
+
start_time: string;
|
|
57
|
+
}, {}, {}, {}, {}>;
|
|
58
|
+
export declare const dagChildWorkflow: import("../..").WorkflowDeclaration<import("../..").UnknownInputType, {}, {}>;
|
|
59
|
+
export declare const durableSpawnDag: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
60
|
+
sleep_duration: number;
|
|
61
|
+
sleep_duration_ms: number;
|
|
62
|
+
spawn_duration: number;
|
|
63
|
+
spawn_result: {};
|
|
64
|
+
}, {}, {}, {}, {}>;
|
|
@@ -8,9 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.waitForSleepTwice = exports.durableWorkflow = exports.SLEEP_TIME = exports.SLEEP_TIME_SECONDS = exports.EVENT_KEY = void 0;
|
|
15
|
+
exports.durableSpawnDag = exports.dagChildWorkflow = exports.memoNowCaching = exports.durableReplayReset = exports.REPLAY_RESET_MEMOIZED_MAX_SECONDS = exports.REPLAY_RESET_SLEEP_SECONDS = exports.durableNonDeterminism = exports.durableWithExplicitSpawn = exports.durableSleepEventSpawn = exports.durableWithBulkSpawn = exports.durableWithSpawn = exports.spawnChildTask = exports.waitForSleepTwice = exports.durableWorkflow = exports.SLEEP_TIME = exports.SLEEP_TIME_SECONDS = exports.EVENT_KEY = void 0;
|
|
13
16
|
const conditions_1 = require("../../conditions");
|
|
17
|
+
const non_determinism_error_1 = require("../../../util/errors/non-determinism-error");
|
|
18
|
+
const sleep_1 = __importDefault(require("../../../util/sleep"));
|
|
14
19
|
const hatchet_client_1 = require("../hatchet-client");
|
|
15
20
|
exports.EVENT_KEY = 'durable-example:event';
|
|
16
21
|
exports.SLEEP_TIME_SECONDS = 2;
|
|
@@ -31,12 +36,16 @@ exports.durableWorkflow.durableTask({
|
|
|
31
36
|
executionTimeout: '10m',
|
|
32
37
|
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
38
|
console.log('Waiting for sleep');
|
|
34
|
-
yield ctx.sleepFor(exports.SLEEP_TIME);
|
|
39
|
+
const sleepResult = yield ctx.sleepFor(exports.SLEEP_TIME);
|
|
35
40
|
console.log('Sleep finished');
|
|
36
41
|
console.log('Waiting for event');
|
|
37
|
-
yield ctx.
|
|
42
|
+
const event = yield ctx.waitForEvent(exports.EVENT_KEY, 'true');
|
|
38
43
|
console.log('Event received');
|
|
39
|
-
return {
|
|
44
|
+
return {
|
|
45
|
+
status: 'success',
|
|
46
|
+
event: event,
|
|
47
|
+
sleep_duration_ms: sleepResult.durationMs,
|
|
48
|
+
};
|
|
40
49
|
}),
|
|
41
50
|
});
|
|
42
51
|
function extractKeyAndEventId(waitResult) {
|
|
@@ -46,10 +55,10 @@ function extractKeyAndEventId(waitResult) {
|
|
|
46
55
|
if (obj && typeof obj === 'object') {
|
|
47
56
|
const [key] = Object.keys(obj);
|
|
48
57
|
const inner = obj[key];
|
|
49
|
-
if (inner && typeof inner === 'object') {
|
|
58
|
+
if (inner && typeof inner === 'object' && !Array.isArray(inner)) {
|
|
50
59
|
const [eventId] = Object.keys(inner);
|
|
51
60
|
if (eventId) {
|
|
52
|
-
return { key
|
|
61
|
+
return { key, eventId };
|
|
53
62
|
}
|
|
54
63
|
}
|
|
55
64
|
if (key) {
|
|
@@ -108,8 +117,154 @@ exports.waitForSleepTwice = hatchet_client_1.hatchet.durableTask({
|
|
|
108
117
|
return { runtime: Math.round((Date.now() - start) / 1000) };
|
|
109
118
|
}
|
|
110
119
|
catch (e) {
|
|
111
|
-
// treat cancellation as a successful completion for parity with Python sample
|
|
112
120
|
return { runtime: -1 };
|
|
113
121
|
}
|
|
114
122
|
}),
|
|
115
123
|
});
|
|
124
|
+
// --- Spawn child from durable task ---
|
|
125
|
+
exports.spawnChildTask = hatchet_client_1.hatchet.task({
|
|
126
|
+
name: 'spawn-child-task',
|
|
127
|
+
fn: (input) => __awaiter(void 0, void 0, void 0, function* () {
|
|
128
|
+
var _a;
|
|
129
|
+
return { message: `hello from child ${(_a = input.n) !== null && _a !== void 0 ? _a : 1}` };
|
|
130
|
+
}),
|
|
131
|
+
});
|
|
132
|
+
exports.durableWithSpawn = hatchet_client_1.hatchet.durableTask({
|
|
133
|
+
name: 'durable-with-spawn',
|
|
134
|
+
executionTimeout: '10s',
|
|
135
|
+
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
136
|
+
const childResult = yield exports.spawnChildTask.run({});
|
|
137
|
+
return { child_output: childResult };
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
exports.durableWithBulkSpawn = hatchet_client_1.hatchet.durableTask({
|
|
141
|
+
name: 'durable-with-bulk-spawn',
|
|
142
|
+
executionTimeout: '10m',
|
|
143
|
+
fn: (input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
144
|
+
var _a;
|
|
145
|
+
const n = (_a = input.n) !== null && _a !== void 0 ? _a : 10;
|
|
146
|
+
const inputs = Array.from({ length: n }, (_, i) => ({ n: i }));
|
|
147
|
+
const childResults = yield exports.spawnChildTask.run(inputs);
|
|
148
|
+
return { child_outputs: childResults };
|
|
149
|
+
}),
|
|
150
|
+
});
|
|
151
|
+
exports.durableSleepEventSpawn = hatchet_client_1.hatchet.durableTask({
|
|
152
|
+
name: 'durable-sleep-event-spawn',
|
|
153
|
+
executionTimeout: '10m',
|
|
154
|
+
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
155
|
+
const start = Date.now();
|
|
156
|
+
yield ctx.sleepFor(exports.SLEEP_TIME);
|
|
157
|
+
yield ctx.waitForEvent(exports.EVENT_KEY, 'true');
|
|
158
|
+
const childResult = yield exports.spawnChildTask.run({});
|
|
159
|
+
return {
|
|
160
|
+
runtime: (Date.now() - start) / 1000,
|
|
161
|
+
child_output: childResult,
|
|
162
|
+
};
|
|
163
|
+
}),
|
|
164
|
+
});
|
|
165
|
+
// --- Spawn child using explicit ctx.spawnChild ---
|
|
166
|
+
exports.durableWithExplicitSpawn = hatchet_client_1.hatchet.durableTask({
|
|
167
|
+
name: 'durable-with-explicit-spawn',
|
|
168
|
+
executionTimeout: '10m',
|
|
169
|
+
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
170
|
+
const childResult = yield ctx.spawnChild(exports.spawnChildTask, {});
|
|
171
|
+
return { child_output: childResult };
|
|
172
|
+
}),
|
|
173
|
+
});
|
|
174
|
+
// --- Non-determinism detection ---
|
|
175
|
+
exports.durableNonDeterminism = hatchet_client_1.hatchet.durableTask({
|
|
176
|
+
name: 'durable-non-determinism',
|
|
177
|
+
executionTimeout: '10s',
|
|
178
|
+
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
179
|
+
const sleepTime = ctx.invocationCount * 2;
|
|
180
|
+
try {
|
|
181
|
+
yield ctx.sleepFor(`${sleepTime}s`);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
if (e instanceof non_determinism_error_1.NonDeterminismError) {
|
|
185
|
+
return {
|
|
186
|
+
attempt_number: ctx.invocationCount,
|
|
187
|
+
sleep_time: sleepTime,
|
|
188
|
+
non_determinism_detected: true,
|
|
189
|
+
node_id: e.nodeId,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
throw e;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
attempt_number: ctx.invocationCount,
|
|
196
|
+
sleep_time: sleepTime,
|
|
197
|
+
non_determinism_detected: false,
|
|
198
|
+
};
|
|
199
|
+
}),
|
|
200
|
+
});
|
|
201
|
+
// --- Replay reset ---
|
|
202
|
+
exports.REPLAY_RESET_SLEEP_SECONDS = 3;
|
|
203
|
+
/** Max duration (seconds) for a replayed/memoized step; above this we treat it as a real sleep. */
|
|
204
|
+
exports.REPLAY_RESET_MEMOIZED_MAX_SECONDS = 5;
|
|
205
|
+
const REPLAY_RESET_SLEEP = `${exports.REPLAY_RESET_SLEEP_SECONDS}s`;
|
|
206
|
+
exports.durableReplayReset = hatchet_client_1.hatchet.durableTask({
|
|
207
|
+
name: 'durable-replay-reset',
|
|
208
|
+
executionTimeout: '20s',
|
|
209
|
+
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
210
|
+
let start = Date.now();
|
|
211
|
+
yield ctx.sleepFor(REPLAY_RESET_SLEEP);
|
|
212
|
+
const sleep1Duration = (Date.now() - start) / 1000;
|
|
213
|
+
start = Date.now();
|
|
214
|
+
yield ctx.sleepFor(REPLAY_RESET_SLEEP);
|
|
215
|
+
const sleep2Duration = (Date.now() - start) / 1000;
|
|
216
|
+
start = Date.now();
|
|
217
|
+
yield ctx.sleepFor(REPLAY_RESET_SLEEP);
|
|
218
|
+
const sleep3Duration = (Date.now() - start) / 1000;
|
|
219
|
+
return {
|
|
220
|
+
sleep_1_duration: sleep1Duration,
|
|
221
|
+
sleep_2_duration: sleep2Duration,
|
|
222
|
+
sleep_3_duration: sleep3Duration,
|
|
223
|
+
};
|
|
224
|
+
}),
|
|
225
|
+
});
|
|
226
|
+
exports.memoNowCaching = hatchet_client_1.hatchet.durableTask({
|
|
227
|
+
name: 'memo-now-caching',
|
|
228
|
+
executionTimeout: '10m',
|
|
229
|
+
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
230
|
+
const now = yield ctx.now();
|
|
231
|
+
return { start_time: now.toISOString() };
|
|
232
|
+
}),
|
|
233
|
+
});
|
|
234
|
+
// --- Spawn DAG from durable task ---
|
|
235
|
+
exports.dagChildWorkflow = hatchet_client_1.hatchet.workflow({
|
|
236
|
+
name: 'dag-child-workflow-ts',
|
|
237
|
+
});
|
|
238
|
+
const dagChild1 = exports.dagChildWorkflow.task({
|
|
239
|
+
name: 'dag-child-1',
|
|
240
|
+
fn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
241
|
+
yield (0, sleep_1.default)(1000);
|
|
242
|
+
return { result: 'child1' };
|
|
243
|
+
}),
|
|
244
|
+
});
|
|
245
|
+
exports.dagChildWorkflow.task({
|
|
246
|
+
name: 'dag-child-2',
|
|
247
|
+
parents: [dagChild1],
|
|
248
|
+
fn: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
249
|
+
yield (0, sleep_1.default)(2000);
|
|
250
|
+
return { result: 'child2' };
|
|
251
|
+
}),
|
|
252
|
+
});
|
|
253
|
+
exports.durableSpawnDag = hatchet_client_1.hatchet.durableTask({
|
|
254
|
+
name: 'durable-spawn-dag',
|
|
255
|
+
executionTimeout: '10s',
|
|
256
|
+
fn: (_input, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
257
|
+
const sleepStart = Date.now();
|
|
258
|
+
const sleepResult = yield ctx.sleepFor(exports.SLEEP_TIME);
|
|
259
|
+
const sleepDuration = (Date.now() - sleepStart) / 1000;
|
|
260
|
+
const spawnStart = Date.now();
|
|
261
|
+
const spawnResult = yield exports.dagChildWorkflow.run({});
|
|
262
|
+
const spawnDuration = (Date.now() - spawnStart) / 1000;
|
|
263
|
+
return {
|
|
264
|
+
sleep_duration: sleepDuration,
|
|
265
|
+
sleep_duration_ms: sleepResult.durationMs,
|
|
266
|
+
spawn_duration: spawnDuration,
|
|
267
|
+
spawn_result: spawnResult,
|
|
268
|
+
};
|
|
269
|
+
}),
|
|
270
|
+
});
|
|
@@ -17,9 +17,7 @@ exports.durableEvent = hatchet_client_1.hatchet.durableTask({
|
|
|
17
17
|
name: 'durable-event',
|
|
18
18
|
executionTimeout: '10m',
|
|
19
19
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
-
const res = ctx.
|
|
21
|
-
eventKey: 'user:update',
|
|
22
|
-
});
|
|
20
|
+
const res = yield ctx.waitForEvent('user:update');
|
|
23
21
|
console.log('res', res);
|
|
24
22
|
return {
|
|
25
23
|
Value: 'done',
|
|
@@ -32,10 +30,7 @@ exports.durableEventWithFilter = hatchet_client_1.hatchet.durableTask({
|
|
|
32
30
|
executionTimeout: '10m',
|
|
33
31
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
32
|
// > Durable Event With Filter
|
|
35
|
-
const res = ctx.
|
|
36
|
-
eventKey: 'user:update',
|
|
37
|
-
expression: "input.userId == '1234'",
|
|
38
|
-
});
|
|
33
|
+
const res = yield ctx.waitForEvent('user:update', "input.userId == '1234'");
|
|
39
34
|
// !!
|
|
40
35
|
console.log('res', res);
|
|
41
36
|
return {
|
|
@@ -9,17 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.durableEventWithFilter = exports.durableEvent = void 0;
|
|
13
|
-
// import sleep from '../../../util/sleep.js';
|
|
12
|
+
exports.durableEventWithFilter = exports.durableEvent = exports.EVENT_KEY = void 0;
|
|
14
13
|
const hatchet_client_1 = require("../hatchet-client");
|
|
14
|
+
exports.EVENT_KEY = 'user:update';
|
|
15
15
|
// > Durable Event
|
|
16
16
|
exports.durableEvent = hatchet_client_1.hatchet.durableTask({
|
|
17
17
|
name: 'durable-event',
|
|
18
18
|
executionTimeout: '10m',
|
|
19
19
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
-
const res = ctx.
|
|
21
|
-
eventKey: 'user:update',
|
|
22
|
-
});
|
|
20
|
+
const res = yield ctx.waitForEvent(exports.EVENT_KEY);
|
|
23
21
|
console.log('res', res);
|
|
24
22
|
return {
|
|
25
23
|
Value: 'done',
|
|
@@ -32,10 +30,7 @@ exports.durableEventWithFilter = hatchet_client_1.hatchet.durableTask({
|
|
|
32
30
|
executionTimeout: '10m',
|
|
33
31
|
fn: (_, ctx) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
32
|
// > Durable Event With Filter
|
|
35
|
-
const res = ctx.
|
|
36
|
-
eventKey: 'user:update',
|
|
37
|
-
expression: "input.userId == '1234'",
|
|
38
|
-
});
|
|
33
|
+
const res = yield ctx.waitForEvent(exports.EVENT_KEY, "input.userId == '1234'");
|
|
39
34
|
// !!
|
|
40
35
|
console.log('res', res);
|
|
41
36
|
return {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
/**
|
|
13
|
+
* Dedicated worker for capacity-eviction e2e tests.
|
|
14
|
+
*
|
|
15
|
+
* Runs with durableSlots=1 so that a single waiting durable task triggers
|
|
16
|
+
* capacity pressure and gets evicted (even with ttl=undefined).
|
|
17
|
+
*/
|
|
18
|
+
const hatchet_client_1 = require("../hatchet-client");
|
|
19
|
+
const workflow_1 = require("./workflow");
|
|
20
|
+
function main() {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const worker = yield hatchet_client_1.hatchet.worker('capacity-eviction-worker', {
|
|
23
|
+
durableSlots: 1,
|
|
24
|
+
workflows: [workflow_1.capacityEvictableSleep],
|
|
25
|
+
});
|
|
26
|
+
yield worker.start();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (require.main === module) {
|
|
30
|
+
main();
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
const hatchet_client_1 = require("../hatchet-client");
|
|
13
|
+
const workflow_1 = require("./workflow");
|
|
14
|
+
function main() {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const worker = yield hatchet_client_1.hatchet.worker('eviction-worker', {
|
|
17
|
+
workflows: [
|
|
18
|
+
workflow_1.evictableSleep,
|
|
19
|
+
workflow_1.evictableWaitForEvent,
|
|
20
|
+
workflow_1.evictableChildSpawn,
|
|
21
|
+
workflow_1.evictableChildBulkSpawn,
|
|
22
|
+
workflow_1.multipleEviction,
|
|
23
|
+
workflow_1.nonEvictableSleep,
|
|
24
|
+
workflow_1.childTask,
|
|
25
|
+
workflow_1.bulkChildTask,
|
|
26
|
+
workflow_1.evictableSleepForGracefulTermination,
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
yield worker.start();
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (require.main === module) {
|
|
33
|
+
main();
|
|
34
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const EVICTION_TTL_SECONDS = 5;
|
|
2
|
+
export declare const LONG_SLEEP_SECONDS = 15;
|
|
3
|
+
export declare const EVENT_KEY = "durable-eviction:event";
|
|
4
|
+
export declare const childTask: import("../..").TaskWorkflowDeclaration<import("../..").UnknownInputType, {
|
|
5
|
+
child_status: string;
|
|
6
|
+
}, {}, {}, {}, {}>;
|
|
7
|
+
export declare const evictableSleep: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
8
|
+
status: string;
|
|
9
|
+
}, {}, {}, {}, {}>;
|
|
10
|
+
export declare const evictableSleepForGracefulTermination: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
11
|
+
status: string;
|
|
12
|
+
}, {}, {}, {}, {}>;
|
|
13
|
+
export declare const evictableWaitForEvent: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
14
|
+
status: string;
|
|
15
|
+
}, {}, {}, {}, {}>;
|
|
16
|
+
export declare const evictableChildSpawn: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
17
|
+
child: {
|
|
18
|
+
child_status: string;
|
|
19
|
+
};
|
|
20
|
+
status: string;
|
|
21
|
+
}, {}, {}, {}, {}>;
|
|
22
|
+
export declare const multipleEviction: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
23
|
+
status: string;
|
|
24
|
+
}, {}, {}, {}, {}>;
|
|
25
|
+
export declare const bulkChildTask: import("../..").TaskWorkflowDeclaration<{
|
|
26
|
+
sleepSeconds: number;
|
|
27
|
+
}, {
|
|
28
|
+
sleepSeconds: number;
|
|
29
|
+
status: string;
|
|
30
|
+
}, {}, {}, {}, {}>;
|
|
31
|
+
export declare const evictableChildBulkSpawn: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
32
|
+
child_results: {
|
|
33
|
+
sleepSeconds: number;
|
|
34
|
+
status: string;
|
|
35
|
+
}[];
|
|
36
|
+
status: string;
|
|
37
|
+
}, {}, {}, {}, {}>;
|
|
38
|
+
export declare const CAPACITY_SLEEP_SECONDS = 20;
|
|
39
|
+
export declare const capacityEvictableSleep: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
40
|
+
status: string;
|
|
41
|
+
}, {}, {}, {}, {}>;
|
|
42
|
+
export declare const nonEvictableSleep: import("../..").TaskWorkflowDeclaration<import("../..").JsonObject, {
|
|
43
|
+
status: string;
|
|
44
|
+
}, {}, {}, {}, {}>;
|