@durable-effect/jobs 0.0.1-next.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/LICENSE +21 -0
- package/README.md +490 -0
- package/dist/client/client.d.ts +34 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +427 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/response.d.ts +99 -0
- package/dist/client/response.d.ts.map +1 -0
- package/dist/client/response.js +92 -0
- package/dist/client/response.js.map +1 -0
- package/dist/client/types.d.ts +242 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +3 -0
- package/dist/client/types.js.map +1 -0
- package/dist/definitions/continuous.d.ts +110 -0
- package/dist/definitions/continuous.d.ts.map +1 -0
- package/dist/definitions/continuous.js +79 -0
- package/dist/definitions/continuous.js.map +1 -0
- package/dist/definitions/debounce.d.ts +67 -0
- package/dist/definitions/debounce.d.ts.map +1 -0
- package/dist/definitions/debounce.js +28 -0
- package/dist/definitions/debounce.js.map +1 -0
- package/dist/definitions/index.d.ts +4 -0
- package/dist/definitions/index.d.ts.map +1 -0
- package/dist/definitions/index.js +5 -0
- package/dist/definitions/index.js.map +1 -0
- package/dist/definitions/task.d.ts +234 -0
- package/dist/definitions/task.d.ts.map +1 -0
- package/dist/definitions/task.js +106 -0
- package/dist/definitions/task.js.map +1 -0
- package/dist/engine/engine.d.ts +60 -0
- package/dist/engine/engine.d.ts.map +1 -0
- package/dist/engine/engine.js +89 -0
- package/dist/engine/engine.js.map +1 -0
- package/dist/engine/index.d.ts +3 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +3 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/types.d.ts +53 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +3 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/errors.d.ts +119 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +80 -0
- package/dist/errors.js.map +1 -0
- package/dist/factory.d.ts +97 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +94 -0
- package/dist/factory.js.map +1 -0
- package/dist/handlers/continuous/context.d.ts +25 -0
- package/dist/handlers/continuous/context.d.ts.map +1 -0
- package/dist/handlers/continuous/context.js +38 -0
- package/dist/handlers/continuous/context.js.map +1 -0
- package/dist/handlers/continuous/executor.d.ts +10 -0
- package/dist/handlers/continuous/executor.d.ts.map +1 -0
- package/dist/handlers/continuous/executor.js +83 -0
- package/dist/handlers/continuous/executor.js.map +1 -0
- package/dist/handlers/continuous/handler.d.ts +14 -0
- package/dist/handlers/continuous/handler.d.ts.map +1 -0
- package/dist/handlers/continuous/handler.js +283 -0
- package/dist/handlers/continuous/handler.js.map +1 -0
- package/dist/handlers/continuous/index.d.ts +4 -0
- package/dist/handlers/continuous/index.d.ts.map +1 -0
- package/dist/handlers/continuous/index.js +4 -0
- package/dist/handlers/continuous/index.js.map +1 -0
- package/dist/handlers/continuous/types.d.ts +36 -0
- package/dist/handlers/continuous/types.d.ts.map +1 -0
- package/dist/handlers/continuous/types.js +3 -0
- package/dist/handlers/continuous/types.js.map +1 -0
- package/dist/handlers/debounce/handler.d.ts +14 -0
- package/dist/handlers/debounce/handler.d.ts.map +1 -0
- package/dist/handlers/debounce/handler.js +261 -0
- package/dist/handlers/debounce/handler.js.map +1 -0
- package/dist/handlers/debounce/index.d.ts +3 -0
- package/dist/handlers/debounce/index.d.ts.map +1 -0
- package/dist/handlers/debounce/index.js +3 -0
- package/dist/handlers/debounce/index.js.map +1 -0
- package/dist/handlers/debounce/types.d.ts +10 -0
- package/dist/handlers/debounce/types.d.ts.map +1 -0
- package/dist/handlers/debounce/types.js +3 -0
- package/dist/handlers/debounce/types.js.map +1 -0
- package/dist/handlers/index.d.ts +14 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +25 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/task/context.d.ts +35 -0
- package/dist/handlers/task/context.d.ts.map +1 -0
- package/dist/handlers/task/context.js +156 -0
- package/dist/handlers/task/context.js.map +1 -0
- package/dist/handlers/task/handler.d.ts +13 -0
- package/dist/handlers/task/handler.d.ts.map +1 -0
- package/dist/handlers/task/handler.js +280 -0
- package/dist/handlers/task/handler.js.map +1 -0
- package/dist/handlers/task/index.d.ts +3 -0
- package/dist/handlers/task/index.d.ts.map +1 -0
- package/dist/handlers/task/index.js +2 -0
- package/dist/handlers/task/index.js.map +1 -0
- package/dist/handlers/task/types.d.ts +10 -0
- package/dist/handlers/task/types.d.ts.map +1 -0
- package/dist/handlers/task/types.js +3 -0
- package/dist/handlers/task/types.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/dist/registry/index.d.ts +5 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +4 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/registry.d.ts +74 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +159 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/registry/typed.d.ts +146 -0
- package/dist/registry/typed.d.ts.map +1 -0
- package/dist/registry/typed.js +29 -0
- package/dist/registry/typed.js.map +1 -0
- package/dist/registry/types.d.ts +497 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +3 -0
- package/dist/registry/types.js.map +1 -0
- package/dist/retry/errors.d.ts +31 -0
- package/dist/retry/errors.d.ts.map +1 -0
- package/dist/retry/errors.js +22 -0
- package/dist/retry/errors.js.map +1 -0
- package/dist/retry/executor.d.ts +53 -0
- package/dist/retry/executor.d.ts.map +1 -0
- package/dist/retry/executor.js +112 -0
- package/dist/retry/executor.js.map +1 -0
- package/dist/retry/index.d.ts +4 -0
- package/dist/retry/index.d.ts.map +1 -0
- package/dist/retry/index.js +4 -0
- package/dist/retry/index.js.map +1 -0
- package/dist/retry/types.d.ts +29 -0
- package/dist/retry/types.d.ts.map +1 -0
- package/dist/retry/types.js +3 -0
- package/dist/retry/types.js.map +1 -0
- package/dist/runtime/dispatcher.d.ts +39 -0
- package/dist/runtime/dispatcher.d.ts.map +1 -0
- package/dist/runtime/dispatcher.js +76 -0
- package/dist/runtime/dispatcher.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +6 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/runtime.d.ts +88 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +116 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/types.d.ts +182 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +3 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/services/alarm.d.ts +37 -0
- package/dist/services/alarm.d.ts.map +1 -0
- package/dist/services/alarm.js +39 -0
- package/dist/services/alarm.js.map +1 -0
- package/dist/services/cleanup.d.ts +27 -0
- package/dist/services/cleanup.d.ts.map +1 -0
- package/dist/services/cleanup.js +25 -0
- package/dist/services/cleanup.js.map +1 -0
- package/dist/services/entity-state.d.ts +49 -0
- package/dist/services/entity-state.d.ts.map +1 -0
- package/dist/services/entity-state.js +72 -0
- package/dist/services/entity-state.js.map +1 -0
- package/dist/services/execution.d.ts +70 -0
- package/dist/services/execution.d.ts.map +1 -0
- package/dist/services/execution.js +159 -0
- package/dist/services/execution.js.map +1 -0
- package/dist/services/execution_test.d.ts +13 -0
- package/dist/services/execution_test.d.ts.map +1 -0
- package/dist/services/execution_test.js +11 -0
- package/dist/services/execution_test.js.map +1 -0
- package/dist/services/idempotency.d.ts +36 -0
- package/dist/services/idempotency.d.ts.map +1 -0
- package/dist/services/idempotency.js +48 -0
- package/dist/services/idempotency.js.map +1 -0
- package/dist/services/index.d.ts +19 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +33 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/metadata.d.ts +64 -0
- package/dist/services/metadata.d.ts.map +1 -0
- package/dist/services/metadata.js +56 -0
- package/dist/services/metadata.js.map +1 -0
- package/dist/services/registry.d.ts +19 -0
- package/dist/services/registry.d.ts.map +1 -0
- package/dist/services/registry.js +17 -0
- package/dist/services/registry.js.map +1 -0
- package/dist/storage-keys.d.ts +38 -0
- package/dist/storage-keys.d.ts.map +1 -0
- package/dist/storage-keys.js +47 -0
- package/dist/storage-keys.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
// packages/jobs/src/handlers/continuous/handler.ts
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import { RuntimeAdapter, StorageAdapter, } from "@durable-effect/core";
|
|
4
|
+
import { MetadataService } from "../../services/metadata";
|
|
5
|
+
import { AlarmService } from "../../services/alarm";
|
|
6
|
+
import { createEntityStateService } from "../../services/entity-state";
|
|
7
|
+
import { RegistryService } from "../../services/registry";
|
|
8
|
+
import { JobExecutionService } from "../../services/execution";
|
|
9
|
+
import { KEYS } from "../../storage-keys";
|
|
10
|
+
import { JobNotFoundError, ExecutionError, } from "../../errors";
|
|
11
|
+
import { RetryExecutor } from "../../retry";
|
|
12
|
+
import { createContinuousContext } from "./context";
|
|
13
|
+
export class ContinuousHandler extends Context.Tag("@durable-effect/jobs/ContinuousHandler")() {
|
|
14
|
+
}
|
|
15
|
+
export const ContinuousHandlerLayer = Layer.effect(ContinuousHandler, Effect.gen(function* () {
|
|
16
|
+
const registryService = yield* RegistryService;
|
|
17
|
+
const metadata = yield* MetadataService;
|
|
18
|
+
const alarm = yield* AlarmService;
|
|
19
|
+
const runtime = yield* RuntimeAdapter;
|
|
20
|
+
const storage = yield* StorageAdapter;
|
|
21
|
+
const execution = yield* JobExecutionService;
|
|
22
|
+
const retryExecutor = yield* RetryExecutor;
|
|
23
|
+
const getDefinition = (name) => {
|
|
24
|
+
const def = registryService.registry.continuous[name];
|
|
25
|
+
if (!def) {
|
|
26
|
+
return Effect.fail(new JobNotFoundError({ type: "continuous", name }));
|
|
27
|
+
}
|
|
28
|
+
return Effect.succeed(def);
|
|
29
|
+
};
|
|
30
|
+
const getRunCount = () => storage
|
|
31
|
+
.get(KEYS.CONTINUOUS.RUN_COUNT)
|
|
32
|
+
.pipe(Effect.map((count) => count ?? 0));
|
|
33
|
+
const incrementRunCount = () => Effect.gen(function* () {
|
|
34
|
+
const current = yield* getRunCount();
|
|
35
|
+
const next = current + 1;
|
|
36
|
+
yield* storage.put(KEYS.CONTINUOUS.RUN_COUNT, next);
|
|
37
|
+
return next;
|
|
38
|
+
});
|
|
39
|
+
const updateLastExecutedAt = () => Effect.gen(function* () {
|
|
40
|
+
const now = yield* runtime.now();
|
|
41
|
+
yield* storage.put(KEYS.CONTINUOUS.LAST_EXECUTED_AT, now);
|
|
42
|
+
});
|
|
43
|
+
const scheduleNext = (def) => {
|
|
44
|
+
const schedule = def.schedule;
|
|
45
|
+
switch (schedule._tag) {
|
|
46
|
+
case "Every":
|
|
47
|
+
return alarm.schedule(schedule.interval);
|
|
48
|
+
case "Cron":
|
|
49
|
+
return Effect.fail(new ExecutionError({
|
|
50
|
+
jobType: "continuous",
|
|
51
|
+
jobName: def.name,
|
|
52
|
+
instanceId: runtime.instanceId,
|
|
53
|
+
cause: new Error("Cron schedules are not supported yet"),
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const runExecution = (def, runCount) => execution.execute({
|
|
58
|
+
jobType: "continuous",
|
|
59
|
+
jobName: def.name,
|
|
60
|
+
schema: def.stateSchema,
|
|
61
|
+
retryConfig: def.retry,
|
|
62
|
+
runCount,
|
|
63
|
+
run: (ctx) => def.execute(ctx),
|
|
64
|
+
createContext: (base) => {
|
|
65
|
+
const proxyHolder = {
|
|
66
|
+
get current() {
|
|
67
|
+
return base.getState();
|
|
68
|
+
},
|
|
69
|
+
set current(val) {
|
|
70
|
+
base.setState(val);
|
|
71
|
+
},
|
|
72
|
+
get dirty() { return true; }, // Dummy, handled by service
|
|
73
|
+
set dirty(_) { }
|
|
74
|
+
};
|
|
75
|
+
return createContinuousContext(proxyHolder, base.instanceId, base.runCount, def.name, base.attempt);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
const handleStart = (def, request) => Effect.gen(function* () {
|
|
79
|
+
const existing = yield* metadata.get();
|
|
80
|
+
if (existing) {
|
|
81
|
+
return {
|
|
82
|
+
_type: "continuous.start",
|
|
83
|
+
instanceId: runtime.instanceId,
|
|
84
|
+
created: false,
|
|
85
|
+
status: existing.status,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
yield* metadata.initialize("continuous", request.name);
|
|
89
|
+
// Initial state set
|
|
90
|
+
// TODO: ExecutionService handles loading, but here we need to set INITIAL state
|
|
91
|
+
// We can use execution service to "seed" state? No, we should just use storage directly for init.
|
|
92
|
+
// Or we use a special "init" execution?
|
|
93
|
+
// Let's use direct storage access for init as before.
|
|
94
|
+
const stateService = yield* createEntityStateService(def.stateSchema).pipe(Effect.provideService(StorageAdapter, storage));
|
|
95
|
+
yield* stateService.set(request.input);
|
|
96
|
+
yield* storage.put(KEYS.CONTINUOUS.RUN_COUNT, 0);
|
|
97
|
+
yield* metadata.updateStatus("running");
|
|
98
|
+
let status = "running";
|
|
99
|
+
if (def.startImmediately !== false) {
|
|
100
|
+
const runCount = yield* incrementRunCount();
|
|
101
|
+
const result = yield* runExecution(def, runCount);
|
|
102
|
+
if (result.terminated) {
|
|
103
|
+
// Terminated - CleanupService has already purged everything
|
|
104
|
+
return {
|
|
105
|
+
_type: "continuous.start",
|
|
106
|
+
instanceId: runtime.instanceId,
|
|
107
|
+
created: true,
|
|
108
|
+
status: "terminated"
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// Only update last executed if successful (or handled error)
|
|
112
|
+
if (result.success) {
|
|
113
|
+
yield* updateLastExecutedAt();
|
|
114
|
+
}
|
|
115
|
+
// If retry scheduled, we don't schedule next run yet (handled by retry alarm)
|
|
116
|
+
if (result.retryScheduled) {
|
|
117
|
+
// Do nothing, alarm is set
|
|
118
|
+
}
|
|
119
|
+
else if (!result.terminated) {
|
|
120
|
+
// Success, schedule next
|
|
121
|
+
yield* scheduleNext(def);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
yield* scheduleNext(def);
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
_type: "continuous.start",
|
|
129
|
+
instanceId: runtime.instanceId,
|
|
130
|
+
created: true,
|
|
131
|
+
status,
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
const handleTerminate = (request) => Effect.gen(function* () {
|
|
135
|
+
const existing = yield* metadata.get();
|
|
136
|
+
if (!existing) {
|
|
137
|
+
return {
|
|
138
|
+
_type: "continuous.terminate",
|
|
139
|
+
terminated: false,
|
|
140
|
+
reason: "not_found",
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Cancel alarm
|
|
144
|
+
yield* alarm.cancel();
|
|
145
|
+
// Delete ALL storage (state, metadata, run count, etc.)
|
|
146
|
+
yield* storage.deleteAll();
|
|
147
|
+
return {
|
|
148
|
+
_type: "continuous.terminate",
|
|
149
|
+
terminated: true,
|
|
150
|
+
reason: request.reason,
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
const handleTrigger = (def) => Effect.gen(function* () {
|
|
154
|
+
const existing = yield* metadata.get();
|
|
155
|
+
if (!existing ||
|
|
156
|
+
existing.status === "stopped" ||
|
|
157
|
+
existing.status === "terminated") {
|
|
158
|
+
return {
|
|
159
|
+
_type: "continuous.trigger",
|
|
160
|
+
triggered: false,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
// Reset retry state
|
|
164
|
+
yield* retryExecutor.reset().pipe(Effect.ignore);
|
|
165
|
+
const runCount = yield* incrementRunCount();
|
|
166
|
+
const result = yield* runExecution(def, runCount);
|
|
167
|
+
if (result.terminated) {
|
|
168
|
+
// Terminated - CleanupService has already purged everything
|
|
169
|
+
return {
|
|
170
|
+
_type: "continuous.trigger",
|
|
171
|
+
triggered: true,
|
|
172
|
+
terminated: true
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
if (result.retryScheduled) {
|
|
176
|
+
return {
|
|
177
|
+
_type: "continuous.trigger",
|
|
178
|
+
triggered: true,
|
|
179
|
+
retryScheduled: true
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
yield* updateLastExecutedAt();
|
|
183
|
+
yield* scheduleNext(def);
|
|
184
|
+
return {
|
|
185
|
+
_type: "continuous.trigger",
|
|
186
|
+
triggered: true,
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
const handleStatus = () => Effect.gen(function* () {
|
|
190
|
+
const existing = yield* metadata.get();
|
|
191
|
+
if (!existing) {
|
|
192
|
+
return {
|
|
193
|
+
_type: "continuous.status",
|
|
194
|
+
status: "not_found",
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
const runCount = yield* getRunCount();
|
|
198
|
+
const nextRunAt = yield* alarm.getScheduled();
|
|
199
|
+
return {
|
|
200
|
+
_type: "continuous.status",
|
|
201
|
+
status: existing.status,
|
|
202
|
+
nextRunAt,
|
|
203
|
+
runCount,
|
|
204
|
+
stopReason: existing.stopReason,
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
const handleGetState = (def) => Effect.gen(function* () {
|
|
208
|
+
const stateService = yield* createEntityStateService(def.stateSchema).pipe(Effect.provideService(StorageAdapter, storage));
|
|
209
|
+
const state = yield* stateService.get();
|
|
210
|
+
return {
|
|
211
|
+
_type: "continuous.getState",
|
|
212
|
+
state,
|
|
213
|
+
};
|
|
214
|
+
});
|
|
215
|
+
return {
|
|
216
|
+
handle: (request) => Effect.gen(function* () {
|
|
217
|
+
const def = yield* getDefinition(request.name);
|
|
218
|
+
switch (request.action) {
|
|
219
|
+
case "start":
|
|
220
|
+
return yield* handleStart(def, request);
|
|
221
|
+
case "terminate":
|
|
222
|
+
return yield* handleTerminate(request);
|
|
223
|
+
case "trigger":
|
|
224
|
+
return yield* handleTrigger(def);
|
|
225
|
+
case "status":
|
|
226
|
+
return yield* handleStatus();
|
|
227
|
+
case "getState":
|
|
228
|
+
return yield* handleGetState(def);
|
|
229
|
+
}
|
|
230
|
+
}).pipe(Effect.catchTag("StorageError", (e) => Effect.fail(new ExecutionError({
|
|
231
|
+
jobType: "continuous",
|
|
232
|
+
jobName: request.name,
|
|
233
|
+
instanceId: runtime.instanceId,
|
|
234
|
+
cause: e,
|
|
235
|
+
}))), Effect.catchTag("SchedulerError", (e) => Effect.fail(new ExecutionError({
|
|
236
|
+
jobType: "continuous",
|
|
237
|
+
jobName: request.name,
|
|
238
|
+
instanceId: runtime.instanceId,
|
|
239
|
+
cause: e,
|
|
240
|
+
})))),
|
|
241
|
+
handleAlarm: () => Effect.gen(function* () {
|
|
242
|
+
const meta = yield* metadata.get();
|
|
243
|
+
if (!meta ||
|
|
244
|
+
meta.status === "stopped" ||
|
|
245
|
+
meta.status === "terminated") {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const def = yield* getDefinition(meta.name);
|
|
249
|
+
const isRetrying = yield* retryExecutor.isRetrying().pipe(Effect.catchAll(() => Effect.succeed(false)));
|
|
250
|
+
let runCount;
|
|
251
|
+
if (isRetrying) {
|
|
252
|
+
runCount = yield* getRunCount();
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
runCount = yield* incrementRunCount();
|
|
256
|
+
}
|
|
257
|
+
const result = yield* runExecution(def, runCount);
|
|
258
|
+
if (result.retryScheduled) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (result.terminated) {
|
|
262
|
+
// Terminated - CleanupService has already purged everything
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const currentMeta = yield* metadata.get();
|
|
266
|
+
if (currentMeta && currentMeta.status === "running") {
|
|
267
|
+
yield* updateLastExecutedAt();
|
|
268
|
+
yield* scheduleNext(def);
|
|
269
|
+
}
|
|
270
|
+
}).pipe(Effect.catchTag("StorageError", (e) => Effect.fail(new ExecutionError({
|
|
271
|
+
jobType: "continuous",
|
|
272
|
+
jobName: "unknown",
|
|
273
|
+
instanceId: runtime.instanceId,
|
|
274
|
+
cause: e,
|
|
275
|
+
}))), Effect.catchTag("SchedulerError", (e) => Effect.fail(new ExecutionError({
|
|
276
|
+
jobType: "continuous",
|
|
277
|
+
jobName: "unknown",
|
|
278
|
+
instanceId: runtime.instanceId,
|
|
279
|
+
cause: e,
|
|
280
|
+
})))),
|
|
281
|
+
};
|
|
282
|
+
}));
|
|
283
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/handlers/continuous/handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/handlers/continuous/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AACtE,YAAY,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/handlers/continuous/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AAEjD,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAoB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Effect } from "effect";
|
|
2
|
+
import type { ContinuousRequest, ContinuousStartResponse, ContinuousTerminateResponse, ContinuousTriggerResponse, ContinuousStatusResponse, ContinuousGetStateResponse } from "../../runtime/types";
|
|
3
|
+
import type { JobError } from "../../errors";
|
|
4
|
+
/**
|
|
5
|
+
* Union of all continuous response types.
|
|
6
|
+
*/
|
|
7
|
+
export type ContinuousResponse = ContinuousStartResponse | ContinuousTerminateResponse | ContinuousTriggerResponse | ContinuousStatusResponse | ContinuousGetStateResponse;
|
|
8
|
+
/**
|
|
9
|
+
* Continuous handler service interface.
|
|
10
|
+
*
|
|
11
|
+
* Handles all continuous job operations:
|
|
12
|
+
* - start: Initialize and optionally run first execution
|
|
13
|
+
* - terminate: Fully remove job (cancel alarm + delete all state)
|
|
14
|
+
* - trigger: Trigger immediate execution
|
|
15
|
+
* - status: Get current status
|
|
16
|
+
* - getState: Get current state
|
|
17
|
+
* - handleAlarm: Execute on schedule
|
|
18
|
+
*/
|
|
19
|
+
export interface ContinuousHandlerI {
|
|
20
|
+
/**
|
|
21
|
+
* Handle a continuous request.
|
|
22
|
+
*/
|
|
23
|
+
readonly handle: (request: ContinuousRequest) => Effect.Effect<ContinuousResponse, JobError>;
|
|
24
|
+
/**
|
|
25
|
+
* Handle an alarm for this continuous job.
|
|
26
|
+
*/
|
|
27
|
+
readonly handleAlarm: () => Effect.Effect<void, JobError>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Internal state stored alongside user state.
|
|
31
|
+
*/
|
|
32
|
+
export interface ContinuousInternalState {
|
|
33
|
+
readonly runCount: number;
|
|
34
|
+
readonly lastExecutedAt: number | null;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/handlers/continuous/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAM7C;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,uBAAuB,GACvB,2BAA2B,GAC3B,yBAAyB,GACzB,wBAAwB,GACxB,0BAA0B,CAAC;AAM/B;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,CACf,OAAO,EAAE,iBAAiB,KACvB,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAC;IAEjD;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;CAC3D;AAMD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/handlers/continuous/types.ts"],"names":[],"mappings":"AAAA,iDAAiD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
import { RuntimeAdapter, StorageAdapter } from "@durable-effect/core";
|
|
3
|
+
import { MetadataService } from "../../services/metadata";
|
|
4
|
+
import { AlarmService } from "../../services/alarm";
|
|
5
|
+
import { RegistryService } from "../../services/registry";
|
|
6
|
+
import { JobExecutionService } from "../../services/execution";
|
|
7
|
+
import { RetryExecutor } from "../../retry";
|
|
8
|
+
import type { DebounceHandlerI } from "./types";
|
|
9
|
+
declare const DebounceHandler_base: Context.TagClass<DebounceHandler, "@durable-effect/jobs/DebounceHandler", DebounceHandlerI>;
|
|
10
|
+
export declare class DebounceHandler extends DebounceHandler_base {
|
|
11
|
+
}
|
|
12
|
+
export declare const DebounceHandlerLayer: Layer.Layer<DebounceHandler, never, MetadataService | RuntimeAdapter | StorageAdapter | AlarmService | RegistryService | RetryExecutor | JobExecutionService>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/handlers/debounce/handler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAU,KAAK,EAAU,MAAM,QAAQ,CAAC;AACxD,OAAO,EACL,cAAc,EACd,cAAc,EAGf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAwB,MAAM,0BAA0B,CAAC;AAQrF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,SAAS,CAAC;;AAElE,qBAAa,eAAgB,SAAQ,oBAEC;CAAG;AAIzC,eAAO,MAAM,oBAAoB,+JA2VhC,CAAC"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
// packages/jobs/src/handlers/debounce/handler.ts
|
|
2
|
+
import { Context, Effect, Layer, Schema } from "effect";
|
|
3
|
+
import { RuntimeAdapter, StorageAdapter, } from "@durable-effect/core";
|
|
4
|
+
import { MetadataService } from "../../services/metadata";
|
|
5
|
+
import { AlarmService } from "../../services/alarm";
|
|
6
|
+
import { createEntityStateService } from "../../services/entity-state";
|
|
7
|
+
import { RegistryService } from "../../services/registry";
|
|
8
|
+
import { JobExecutionService } from "../../services/execution";
|
|
9
|
+
import { KEYS } from "../../storage-keys";
|
|
10
|
+
import { JobNotFoundError, ExecutionError, UnknownJobTypeError, } from "../../errors";
|
|
11
|
+
import { RetryExecutor } from "../../retry";
|
|
12
|
+
export class DebounceHandler extends Context.Tag("@durable-effect/jobs/DebounceHandler")() {
|
|
13
|
+
}
|
|
14
|
+
export const DebounceHandlerLayer = Layer.effect(DebounceHandler, Effect.gen(function* () {
|
|
15
|
+
const registryService = yield* RegistryService;
|
|
16
|
+
const metadata = yield* MetadataService;
|
|
17
|
+
const alarm = yield* AlarmService;
|
|
18
|
+
const runtime = yield* RuntimeAdapter;
|
|
19
|
+
const storage = yield* StorageAdapter;
|
|
20
|
+
const execution = yield* JobExecutionService;
|
|
21
|
+
const retryExecutor = yield* RetryExecutor;
|
|
22
|
+
const withStorage = (effect) => Effect.provideService(effect, StorageAdapter, storage);
|
|
23
|
+
const getDefinition = (name) => {
|
|
24
|
+
const def = registryService.registry.debounce[name];
|
|
25
|
+
if (!def) {
|
|
26
|
+
return Effect.fail(new JobNotFoundError({ type: "debounce", name }));
|
|
27
|
+
}
|
|
28
|
+
return Effect.succeed(def);
|
|
29
|
+
};
|
|
30
|
+
const getEventCount = () => storage.get(KEYS.DEBOUNCE.EVENT_COUNT).pipe(Effect.map((n) => n ?? 0));
|
|
31
|
+
const setEventCount = (count) => storage.put(KEYS.DEBOUNCE.EVENT_COUNT, count);
|
|
32
|
+
const getStartedAt = () => storage.get(KEYS.DEBOUNCE.STARTED_AT);
|
|
33
|
+
const setStartedAt = () => Effect.gen(function* () {
|
|
34
|
+
const now = yield* runtime.now();
|
|
35
|
+
yield* storage.put(KEYS.DEBOUNCE.STARTED_AT, now);
|
|
36
|
+
});
|
|
37
|
+
const purge = () => Effect.gen(function* () {
|
|
38
|
+
yield* alarm.cancel();
|
|
39
|
+
yield* storage.deleteAll();
|
|
40
|
+
});
|
|
41
|
+
const runFlush = (def, flushReason) => execution.execute({
|
|
42
|
+
jobType: "debounce",
|
|
43
|
+
jobName: def.name,
|
|
44
|
+
schema: def.stateSchema,
|
|
45
|
+
retryConfig: def.retry,
|
|
46
|
+
runCount: 0, // Debounce doesn't track runCount persistently in same way
|
|
47
|
+
run: (ctx) => def.execute(ctx),
|
|
48
|
+
createContext: (base) => {
|
|
49
|
+
return {
|
|
50
|
+
state: Effect.succeed(base.getState()), // Snapshotted state
|
|
51
|
+
eventCount: getEventCount().pipe(Effect.orDie), // Live event count
|
|
52
|
+
instanceId: base.instanceId,
|
|
53
|
+
debounceStartedAt: getStartedAt().pipe(Effect.orDie, Effect.map(t => t ?? 0)),
|
|
54
|
+
executionStartedAt: Date.now(),
|
|
55
|
+
flushReason,
|
|
56
|
+
attempt: base.attempt,
|
|
57
|
+
isRetry: base.isRetry
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
const handleAdd = (def, request) => Effect.gen(function* () {
|
|
62
|
+
const meta = yield* metadata.get();
|
|
63
|
+
const created = !meta;
|
|
64
|
+
if (created) {
|
|
65
|
+
yield* metadata.initialize("debounce", request.name);
|
|
66
|
+
yield* metadata.updateStatus("running");
|
|
67
|
+
yield* setStartedAt();
|
|
68
|
+
yield* setEventCount(0);
|
|
69
|
+
}
|
|
70
|
+
const stateService = yield* withStorage(createEntityStateService(def.stateSchema));
|
|
71
|
+
const currentState = yield* stateService.get();
|
|
72
|
+
const currentCount = yield* getEventCount();
|
|
73
|
+
const nextCount = currentCount + 1;
|
|
74
|
+
const decodeEvent = Schema.decodeUnknown(def.eventSchema);
|
|
75
|
+
const validatedEvent = yield* decodeEvent(request.event).pipe(Effect.mapError((e) => new ExecutionError({
|
|
76
|
+
jobType: "debounce",
|
|
77
|
+
jobName: def.name,
|
|
78
|
+
instanceId: runtime.instanceId,
|
|
79
|
+
cause: e,
|
|
80
|
+
})));
|
|
81
|
+
const stateForContext = currentState ?? validatedEvent;
|
|
82
|
+
const onEvent = def.onEvent;
|
|
83
|
+
// Cast is still needed unless we fix Definition generic constraints
|
|
84
|
+
const reducedState = yield* onEvent({
|
|
85
|
+
event: validatedEvent,
|
|
86
|
+
state: stateForContext,
|
|
87
|
+
eventCount: nextCount,
|
|
88
|
+
instanceId: runtime.instanceId,
|
|
89
|
+
});
|
|
90
|
+
yield* stateService.set(reducedState);
|
|
91
|
+
yield* setEventCount(nextCount);
|
|
92
|
+
if (created) {
|
|
93
|
+
yield* alarm.schedule(def.flushAfter);
|
|
94
|
+
}
|
|
95
|
+
const willFlushAt = yield* alarm.getScheduled();
|
|
96
|
+
if (def.maxEvents !== undefined && nextCount >= def.maxEvents) {
|
|
97
|
+
// Immediate flush
|
|
98
|
+
const result = yield* runFlush(def, "maxEvents");
|
|
99
|
+
if (result.success) {
|
|
100
|
+
// Success - purge state after flush
|
|
101
|
+
yield* purge();
|
|
102
|
+
}
|
|
103
|
+
else if (result.terminated) {
|
|
104
|
+
// Terminated by CleanupService - already purged
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
_type: "debounce.add",
|
|
108
|
+
instanceId: runtime.instanceId,
|
|
109
|
+
eventCount: nextCount,
|
|
110
|
+
willFlushAt: result.retryScheduled ? ((yield* alarm.getScheduled()) ?? null) : null,
|
|
111
|
+
created,
|
|
112
|
+
retryScheduled: result.retryScheduled,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
_type: "debounce.add",
|
|
117
|
+
instanceId: runtime.instanceId,
|
|
118
|
+
eventCount: nextCount,
|
|
119
|
+
willFlushAt: willFlushAt ?? null,
|
|
120
|
+
created,
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
const handleFlush = (def, reason) => Effect.gen(function* () {
|
|
124
|
+
const meta = yield* metadata.get();
|
|
125
|
+
if (!meta) {
|
|
126
|
+
return {
|
|
127
|
+
_type: "debounce.flush",
|
|
128
|
+
flushed: false,
|
|
129
|
+
eventCount: 0,
|
|
130
|
+
reason: "empty",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const eventCount = yield* getEventCount();
|
|
134
|
+
if (eventCount === 0) {
|
|
135
|
+
yield* purge();
|
|
136
|
+
return {
|
|
137
|
+
_type: "debounce.flush",
|
|
138
|
+
flushed: false,
|
|
139
|
+
eventCount: 0,
|
|
140
|
+
reason: "empty",
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const result = yield* runFlush(def, reason);
|
|
144
|
+
if (result.success) {
|
|
145
|
+
// Success - purge state after flush
|
|
146
|
+
yield* purge();
|
|
147
|
+
}
|
|
148
|
+
else if (result.terminated) {
|
|
149
|
+
// Terminated by CleanupService - already purged
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
_type: "debounce.flush",
|
|
153
|
+
flushed: true,
|
|
154
|
+
eventCount,
|
|
155
|
+
reason,
|
|
156
|
+
retryScheduled: result.retryScheduled
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
const handleClear = () => Effect.gen(function* () {
|
|
160
|
+
const meta = yield* metadata.get();
|
|
161
|
+
if (!meta) {
|
|
162
|
+
return {
|
|
163
|
+
_type: "debounce.clear",
|
|
164
|
+
cleared: false,
|
|
165
|
+
discardedEvents: 0,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const eventCount = yield* getEventCount();
|
|
169
|
+
yield* purge();
|
|
170
|
+
return {
|
|
171
|
+
_type: "debounce.clear",
|
|
172
|
+
cleared: true,
|
|
173
|
+
discardedEvents: eventCount,
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
const handleStatus = () => Effect.gen(function* () {
|
|
177
|
+
const meta = yield* metadata.get();
|
|
178
|
+
if (!meta) {
|
|
179
|
+
return {
|
|
180
|
+
_type: "debounce.status",
|
|
181
|
+
status: "not_found",
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const eventCount = yield* getEventCount();
|
|
185
|
+
const startedAt = yield* getStartedAt();
|
|
186
|
+
const willFlushAt = yield* alarm.getScheduled();
|
|
187
|
+
return {
|
|
188
|
+
_type: "debounce.status",
|
|
189
|
+
status: eventCount > 0 ? "debouncing" : "idle",
|
|
190
|
+
eventCount,
|
|
191
|
+
startedAt,
|
|
192
|
+
willFlushAt: willFlushAt ?? undefined,
|
|
193
|
+
};
|
|
194
|
+
});
|
|
195
|
+
const handleGetState = (def) => Effect.gen(function* () {
|
|
196
|
+
const stateService = yield* withStorage(createEntityStateService(def.stateSchema));
|
|
197
|
+
const state = yield* stateService.get();
|
|
198
|
+
return {
|
|
199
|
+
_type: "debounce.getState",
|
|
200
|
+
state,
|
|
201
|
+
};
|
|
202
|
+
});
|
|
203
|
+
return {
|
|
204
|
+
handle: (request) => Effect.gen(function* () {
|
|
205
|
+
const def = yield* getDefinition(request.name);
|
|
206
|
+
switch (request.action) {
|
|
207
|
+
case "add":
|
|
208
|
+
return yield* handleAdd(def, request);
|
|
209
|
+
case "flush":
|
|
210
|
+
return yield* handleFlush(def, "manual");
|
|
211
|
+
case "clear":
|
|
212
|
+
return yield* handleClear();
|
|
213
|
+
case "status":
|
|
214
|
+
return yield* handleStatus();
|
|
215
|
+
case "getState":
|
|
216
|
+
return yield* handleGetState(def);
|
|
217
|
+
default:
|
|
218
|
+
return yield* Effect.fail(new UnknownJobTypeError({ type: `debounce/${request.action}` }));
|
|
219
|
+
}
|
|
220
|
+
}).pipe(Effect.catchTag("StorageError", (e) => Effect.fail(new ExecutionError({
|
|
221
|
+
jobType: "debounce",
|
|
222
|
+
jobName: request.name,
|
|
223
|
+
instanceId: runtime.instanceId,
|
|
224
|
+
cause: e,
|
|
225
|
+
}))), Effect.catchTag("SchedulerError", (e) => Effect.fail(new ExecutionError({
|
|
226
|
+
jobType: "debounce",
|
|
227
|
+
jobName: request.name,
|
|
228
|
+
instanceId: runtime.instanceId,
|
|
229
|
+
cause: e,
|
|
230
|
+
})))),
|
|
231
|
+
handleAlarm: () => Effect.gen(function* () {
|
|
232
|
+
const meta = yield* metadata.get();
|
|
233
|
+
if (!meta || meta.status === "stopped" || meta.status === "terminated") {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const def = yield* getDefinition(meta.name);
|
|
237
|
+
// Check if this is a retry alarm
|
|
238
|
+
const isRetrying = yield* retryExecutor.isRetrying().pipe(Effect.catchAll(() => Effect.succeed(false)));
|
|
239
|
+
// Reset retry state if manual trigger while retrying
|
|
240
|
+
if (!isRetrying) {
|
|
241
|
+
yield* retryExecutor.reset().pipe(Effect.ignore);
|
|
242
|
+
}
|
|
243
|
+
const result = yield* handleFlush(def, "flushAfter");
|
|
244
|
+
void result;
|
|
245
|
+
// Note: handleFlush already purges on success.
|
|
246
|
+
// If retryScheduled, handleFlush returns retryScheduled=true.
|
|
247
|
+
// We don't need to do anything else.
|
|
248
|
+
}).pipe(Effect.catchTag("StorageError", (e) => Effect.fail(new ExecutionError({
|
|
249
|
+
jobType: "debounce",
|
|
250
|
+
jobName: "unknown",
|
|
251
|
+
instanceId: runtime.instanceId,
|
|
252
|
+
cause: e,
|
|
253
|
+
}))), Effect.catchTag("SchedulerError", (e) => Effect.fail(new ExecutionError({
|
|
254
|
+
jobType: "debounce",
|
|
255
|
+
jobName: "unknown",
|
|
256
|
+
instanceId: runtime.instanceId,
|
|
257
|
+
cause: e,
|
|
258
|
+
})))),
|
|
259
|
+
};
|
|
260
|
+
}));
|
|
261
|
+
//# sourceMappingURL=handler.js.map
|