@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,159 @@
|
|
|
1
|
+
// packages/jobs/src/services/execution.ts
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import { RuntimeAdapter, StorageAdapter } from "@durable-effect/core";
|
|
4
|
+
import { RetryExecutor, RetryExhaustedSignal, RetryScheduledSignal, } from "../retry";
|
|
5
|
+
import { createEntityStateService } from "./entity-state";
|
|
6
|
+
import { CleanupService } from "./cleanup";
|
|
7
|
+
import { AlarmService } from "./alarm";
|
|
8
|
+
import { ExecutionError, TerminateSignal } from "../errors";
|
|
9
|
+
// =============================================================================
|
|
10
|
+
// Service Tag
|
|
11
|
+
// =============================================================================
|
|
12
|
+
export class JobExecutionService extends Context.Tag("@durable-effect/jobs/JobExecutionService")() {
|
|
13
|
+
}
|
|
14
|
+
// =============================================================================
|
|
15
|
+
// Implementation
|
|
16
|
+
// =============================================================================
|
|
17
|
+
export const JobExecutionServiceLayer = Layer.effect(JobExecutionService, Effect.gen(function* () {
|
|
18
|
+
const runtime = yield* RuntimeAdapter;
|
|
19
|
+
const storage = yield* StorageAdapter;
|
|
20
|
+
const retryExecutor = yield* RetryExecutor;
|
|
21
|
+
const cleanup = yield* CleanupService;
|
|
22
|
+
const withStorage = (effect) => Effect.provideService(effect, StorageAdapter, storage);
|
|
23
|
+
return {
|
|
24
|
+
execute: (options) => Effect.gen(function* () {
|
|
25
|
+
const { jobType, jobName, schema, retryConfig, run, createContext, onRetryExhausted, } = options;
|
|
26
|
+
const stateService = yield* withStorage(createEntityStateService(schema));
|
|
27
|
+
const loadedState = yield* stateService.get().pipe(withStorage, Effect.mapError((e) => new ExecutionError({
|
|
28
|
+
jobType,
|
|
29
|
+
jobName,
|
|
30
|
+
instanceId: runtime.instanceId,
|
|
31
|
+
cause: e,
|
|
32
|
+
})));
|
|
33
|
+
// If no state and not allowed, treat as already terminated
|
|
34
|
+
if (loadedState === null && !options.allowNullState) {
|
|
35
|
+
return {
|
|
36
|
+
success: false,
|
|
37
|
+
retryScheduled: false,
|
|
38
|
+
terminated: true,
|
|
39
|
+
rescheduled: false,
|
|
40
|
+
retryExhausted: false,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const stateHolder = {
|
|
44
|
+
current: loadedState,
|
|
45
|
+
dirty: false,
|
|
46
|
+
};
|
|
47
|
+
const setState = (s) => {
|
|
48
|
+
stateHolder.current = s;
|
|
49
|
+
stateHolder.dirty = true;
|
|
50
|
+
};
|
|
51
|
+
const updateState = (fn) => {
|
|
52
|
+
if (stateHolder.current !== null) {
|
|
53
|
+
stateHolder.current = fn(stateHolder.current);
|
|
54
|
+
stateHolder.dirty = true;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const attempt = yield* retryExecutor.getAttempt().pipe(Effect.catchAll(() => Effect.succeed(1)));
|
|
58
|
+
const isRetry = attempt > 1;
|
|
59
|
+
const ctx = createContext({
|
|
60
|
+
getState: () => stateHolder.current,
|
|
61
|
+
instanceId: runtime.instanceId,
|
|
62
|
+
runCount: options.runCount ?? 0,
|
|
63
|
+
attempt,
|
|
64
|
+
isRetry,
|
|
65
|
+
setState,
|
|
66
|
+
updateState,
|
|
67
|
+
});
|
|
68
|
+
const executeUserLogic = run(ctx);
|
|
69
|
+
// Build execution effect with optional retry
|
|
70
|
+
const executionEffect = retryConfig
|
|
71
|
+
? retryExecutor.executeWithRetry(executeUserLogic, retryConfig, { jobType, jobName })
|
|
72
|
+
: executeUserLogic;
|
|
73
|
+
// Result tracking
|
|
74
|
+
let success = false;
|
|
75
|
+
let retryScheduled = false;
|
|
76
|
+
let terminated = false;
|
|
77
|
+
let rescheduled = false;
|
|
78
|
+
let retryExhausted = false;
|
|
79
|
+
let terminateReason = undefined;
|
|
80
|
+
const wrapError = (e) => e instanceof ExecutionError
|
|
81
|
+
? e
|
|
82
|
+
: new ExecutionError({
|
|
83
|
+
jobType,
|
|
84
|
+
jobName,
|
|
85
|
+
instanceId: runtime.instanceId,
|
|
86
|
+
cause: e,
|
|
87
|
+
});
|
|
88
|
+
// Execute and handle signals
|
|
89
|
+
yield* executionEffect.pipe(Effect.catchAll((error) => {
|
|
90
|
+
// Handle retry scheduled signal
|
|
91
|
+
if (error instanceof RetryScheduledSignal) {
|
|
92
|
+
retryScheduled = true;
|
|
93
|
+
return Effect.void;
|
|
94
|
+
}
|
|
95
|
+
// Handle terminate signal (from ctx.terminate())
|
|
96
|
+
if (error instanceof TerminateSignal) {
|
|
97
|
+
terminated = true;
|
|
98
|
+
terminateReason = error.reason;
|
|
99
|
+
return cleanup.terminate().pipe(Effect.catchAll(() => Effect.void) // Ignore cleanup errors
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
// Handle retry exhausted signal
|
|
103
|
+
if (error instanceof RetryExhaustedSignal) {
|
|
104
|
+
retryExhausted = true;
|
|
105
|
+
if (onRetryExhausted) {
|
|
106
|
+
// User has handler - create context and call it
|
|
107
|
+
const exhaustedCtx = {
|
|
108
|
+
state: stateHolder.current,
|
|
109
|
+
instanceId: runtime.instanceId,
|
|
110
|
+
jobName,
|
|
111
|
+
attempts: error.attempts,
|
|
112
|
+
totalDurationMs: error.totalDurationMs,
|
|
113
|
+
_terminated: false,
|
|
114
|
+
_rescheduled: false,
|
|
115
|
+
terminate: () => cleanup.terminate().pipe(Effect.tap(() => Effect.sync(() => {
|
|
116
|
+
exhaustedCtx._terminated = true;
|
|
117
|
+
terminated = true;
|
|
118
|
+
})), Effect.catchAll(() => Effect.void)),
|
|
119
|
+
reschedule: (delay) => Effect.gen(function* () {
|
|
120
|
+
const alarm = yield* AlarmService;
|
|
121
|
+
yield* alarm.schedule(delay);
|
|
122
|
+
exhaustedCtx._rescheduled = true;
|
|
123
|
+
rescheduled = true;
|
|
124
|
+
}).pipe(Effect.catchAll(() => Effect.void)),
|
|
125
|
+
};
|
|
126
|
+
return onRetryExhausted(error.lastError, exhaustedCtx).pipe(Effect.tap(() => {
|
|
127
|
+
// If user didn't take action, leave state intact (paused)
|
|
128
|
+
terminated = exhaustedCtx._terminated;
|
|
129
|
+
rescheduled = exhaustedCtx._rescheduled;
|
|
130
|
+
}), Effect.catchAll(() => Effect.void));
|
|
131
|
+
}
|
|
132
|
+
// No handler - default behavior: terminate (purge everything)
|
|
133
|
+
terminated = true;
|
|
134
|
+
terminateReason = `Retry exhausted after ${error.attempts} attempts`;
|
|
135
|
+
return cleanup.terminate().pipe(Effect.catchAll(() => Effect.void));
|
|
136
|
+
}
|
|
137
|
+
// Unknown error - wrap and fail
|
|
138
|
+
return Effect.fail(wrapError(error));
|
|
139
|
+
}));
|
|
140
|
+
// Determine success
|
|
141
|
+
if (!retryScheduled && !terminated && !rescheduled && !retryExhausted) {
|
|
142
|
+
success = true;
|
|
143
|
+
}
|
|
144
|
+
// Save state if modified and not terminated
|
|
145
|
+
if (stateHolder.dirty && !terminated && !retryScheduled && stateHolder.current !== null) {
|
|
146
|
+
yield* stateService.set(stateHolder.current).pipe(withStorage, Effect.mapError(wrapError));
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
success,
|
|
150
|
+
retryScheduled,
|
|
151
|
+
terminated,
|
|
152
|
+
rescheduled,
|
|
153
|
+
retryExhausted,
|
|
154
|
+
terminateReason,
|
|
155
|
+
};
|
|
156
|
+
})
|
|
157
|
+
};
|
|
158
|
+
}));
|
|
159
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/services/execution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Effect, Layer, Context } from "effect";
|
|
2
|
+
export interface Res {
|
|
3
|
+
success: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface Svc {
|
|
6
|
+
exec: () => Effect.Effect<Res, never, never>;
|
|
7
|
+
}
|
|
8
|
+
declare const Svc_base: Context.TagClass<Svc, "Svc", Svc>;
|
|
9
|
+
export declare class Svc extends Svc_base {
|
|
10
|
+
}
|
|
11
|
+
export declare const SvcLayer: Layer.Layer<Svc, never, never>;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=execution_test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution_test.d.ts","sourceRoot":"","sources":["../../src/services/execution_test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,WAAW,GAAG;IAAG,OAAO,EAAE,OAAO,CAAA;CAAE;AAEzC,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;CAC9C;;AAED,qBAAa,GAAI,SAAQ,QAA8B;CAAG;AAE1D,eAAO,MAAM,QAAQ,gCASpB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Effect, Layer, Context } from "effect";
|
|
2
|
+
export class Svc extends Context.Tag("Svc")() {
|
|
3
|
+
}
|
|
4
|
+
export const SvcLayer = Layer.effect(Svc, Effect.gen(function* () {
|
|
5
|
+
return {
|
|
6
|
+
exec: () => Effect.gen(function* () {
|
|
7
|
+
return { success: true };
|
|
8
|
+
})
|
|
9
|
+
};
|
|
10
|
+
}));
|
|
11
|
+
//# sourceMappingURL=execution_test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution_test.js","sourceRoot":"","sources":["../../src/services/execution_test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAQhD,MAAM,OAAO,GAAI,SAAQ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAY;CAAG;AAE1D,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAClC,GAAG,EACH,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC9B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC,CAAC;KACH,CAAC;AACJ,CAAC,CAAC,CACH,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { StorageAdapter, RuntimeAdapter, type StorageError } from "@durable-effect/core";
|
|
3
|
+
/**
|
|
4
|
+
* IdempotencyService tracks processed events for deduplication.
|
|
5
|
+
*
|
|
6
|
+
* Used by Debounce and WorkerPool jobs to ensure exactly-once semantics.
|
|
7
|
+
* Events are identified by a user-provided eventId.
|
|
8
|
+
*/
|
|
9
|
+
export interface IdempotencyServiceI {
|
|
10
|
+
/**
|
|
11
|
+
* Check if an event has already been processed.
|
|
12
|
+
*/
|
|
13
|
+
readonly check: (eventId: string) => Effect.Effect<boolean, StorageError>;
|
|
14
|
+
/**
|
|
15
|
+
* Mark an event as processed.
|
|
16
|
+
*/
|
|
17
|
+
readonly mark: (eventId: string) => Effect.Effect<void, StorageError>;
|
|
18
|
+
/**
|
|
19
|
+
* Check and mark atomically.
|
|
20
|
+
* Returns true if the event was already processed (duplicate).
|
|
21
|
+
* If not processed, marks it and returns false.
|
|
22
|
+
*/
|
|
23
|
+
readonly checkAndMark: (eventId: string) => Effect.Effect<boolean, StorageError>;
|
|
24
|
+
/**
|
|
25
|
+
* Clear an idempotency record.
|
|
26
|
+
* Used during purge or when resetting state.
|
|
27
|
+
* Returns true if key existed, false otherwise.
|
|
28
|
+
*/
|
|
29
|
+
readonly clear: (eventId: string) => Effect.Effect<boolean, StorageError>;
|
|
30
|
+
}
|
|
31
|
+
declare const IdempotencyService_base: Context.TagClass<IdempotencyService, "@durable-effect/jobs/IdempotencyService", IdempotencyServiceI>;
|
|
32
|
+
export declare class IdempotencyService extends IdempotencyService_base {
|
|
33
|
+
}
|
|
34
|
+
export declare const IdempotencyServiceLayer: Layer.Layer<IdempotencyService, never, RuntimeAdapter | StorageAdapter>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=idempotency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/services/idempotency.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAkB9B;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE1E;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAEtE;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAEjF;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;CAC3E;;AAMD,qBAAa,kBAAmB,SAAQ,uBAEI;CAAG;AAM/C,eAAO,MAAM,uBAAuB,yEAgDnC,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// packages/jobs/src/services/idempotency.ts
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import { StorageAdapter, RuntimeAdapter, } from "@durable-effect/core";
|
|
4
|
+
import { KEYS } from "../storage-keys";
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Service Tag
|
|
7
|
+
// =============================================================================
|
|
8
|
+
export class IdempotencyService extends Context.Tag("@durable-effect/jobs/IdempotencyService")() {
|
|
9
|
+
}
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Implementation
|
|
12
|
+
// =============================================================================
|
|
13
|
+
export const IdempotencyServiceLayer = Layer.effect(IdempotencyService, Effect.gen(function* () {
|
|
14
|
+
const storage = yield* StorageAdapter;
|
|
15
|
+
const runtime = yield* RuntimeAdapter;
|
|
16
|
+
const makeKey = (eventId) => `${KEYS.IDEMPOTENCY}${eventId}`;
|
|
17
|
+
return {
|
|
18
|
+
check: (eventId) => Effect.gen(function* () {
|
|
19
|
+
const key = makeKey(eventId);
|
|
20
|
+
const record = yield* storage.get(key);
|
|
21
|
+
return record !== undefined;
|
|
22
|
+
}),
|
|
23
|
+
mark: (eventId) => Effect.gen(function* () {
|
|
24
|
+
const key = makeKey(eventId);
|
|
25
|
+
const now = yield* runtime.now();
|
|
26
|
+
const record = { processedAt: now };
|
|
27
|
+
yield* storage.put(key, record);
|
|
28
|
+
}),
|
|
29
|
+
checkAndMark: (eventId) => Effect.gen(function* () {
|
|
30
|
+
const key = makeKey(eventId);
|
|
31
|
+
const existing = yield* storage.get(key);
|
|
32
|
+
if (existing !== undefined) {
|
|
33
|
+
// Already processed - this is a duplicate
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
// Not processed - mark it now
|
|
37
|
+
const now = yield* runtime.now();
|
|
38
|
+
const record = { processedAt: now };
|
|
39
|
+
yield* storage.put(key, record);
|
|
40
|
+
return false;
|
|
41
|
+
}),
|
|
42
|
+
clear: (eventId) => {
|
|
43
|
+
const key = makeKey(eventId);
|
|
44
|
+
return storage.delete(key);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}));
|
|
48
|
+
//# sourceMappingURL=idempotency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/services/idempotency.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EACL,cAAc,EACd,cAAc,GAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAiDvC,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF,MAAM,OAAO,kBAAmB,SAAQ,OAAO,CAAC,GAAG,CACjD,yCAAyC,CAC1C,EAA2C;CAAG;AAE/C,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAC,MAAM,CACjD,kBAAkB,EAClB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IAEtC,MAAM,OAAO,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,GAAG,OAAO,EAAE,CAAC;IAErE,OAAO;QACL,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE,CACzB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAoB,GAAG,CAAC,CAAC;YAC1D,OAAO,MAAM,KAAK,SAAS,CAAC;QAC9B,CAAC,CAAC;QAEJ,IAAI,EAAE,CAAC,OAAe,EAAE,EAAE,CACxB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,MAAM,GAAsB,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;YACvD,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAClC,CAAC,CAAC;QAEJ,YAAY,EAAE,CAAC,OAAe,EAAE,EAAE,CAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAoB,GAAG,CAAC,CAAC;YAE5D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,0CAA0C;gBAC1C,OAAO,IAAI,CAAC;YACd,CAAC;YAED,8BAA8B;YAC9B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,MAAM,GAAsB,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;YACvD,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAEhC,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEJ,KAAK,EAAE,CAAC,OAAe,EAAE,EAAE;YACzB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YAC7B,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC,CAAC,CACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Layer } from "effect";
|
|
2
|
+
export { MetadataService, MetadataServiceLayer, type MetadataServiceI, type JobMetadata, type JobType, type JobStatus, } from "./metadata";
|
|
3
|
+
export { createEntityStateService, type EntityStateServiceI, } from "./entity-state";
|
|
4
|
+
export { AlarmService, AlarmServiceLayer, type AlarmServiceI } from "./alarm";
|
|
5
|
+
export { IdempotencyService, IdempotencyServiceLayer, type IdempotencyServiceI, } from "./idempotency";
|
|
6
|
+
export { RegistryService, RegistryServiceLayer, type RegistryServiceI, } from "./registry";
|
|
7
|
+
export { JobExecutionService, JobExecutionServiceLayer, type JobExecutionServiceI, type ExecuteOptions, type ExecutionResult, type ExecutionContextBase, type OnRetryExhaustedContext, } from "./execution";
|
|
8
|
+
export { CleanupService, CleanupServiceLayer, type CleanupServiceI, } from "./cleanup";
|
|
9
|
+
/**
|
|
10
|
+
* Combined layer for all runtime services.
|
|
11
|
+
*
|
|
12
|
+
* Requires: StorageAdapter, SchedulerAdapter, RuntimeAdapter
|
|
13
|
+
* Provides: MetadataService, AlarmService, IdempotencyService
|
|
14
|
+
*
|
|
15
|
+
* Note: EntityStateService is NOT included because it's a factory function
|
|
16
|
+
* that creates instances per-schema, not a singleton service.
|
|
17
|
+
*/
|
|
18
|
+
export declare const RuntimeServicesLayer: Layer.Layer<import("./metadata").MetadataService | import("./alarm").AlarmService | import("./idempotency").IdempotencyService, never, import("@durable-effect/core").RuntimeAdapter | import("@durable-effect/core").StorageAdapter | import("@durable-effect/core").SchedulerAdapter>;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG/B,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,SAAS,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,wBAAwB,EACxB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAG9E,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,KAAK,gBAAgB,GACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,KAAK,eAAe,GACrB,MAAM,WAAW,CAAC;AAUnB;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,yRAIhC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// packages/jobs/src/services/index.ts
|
|
2
|
+
import { Layer } from "effect";
|
|
3
|
+
// Metadata
|
|
4
|
+
export { MetadataService, MetadataServiceLayer, } from "./metadata";
|
|
5
|
+
// Entity State
|
|
6
|
+
export { createEntityStateService, } from "./entity-state";
|
|
7
|
+
// Alarm
|
|
8
|
+
export { AlarmService, AlarmServiceLayer } from "./alarm";
|
|
9
|
+
// Idempotency
|
|
10
|
+
export { IdempotencyService, IdempotencyServiceLayer, } from "./idempotency";
|
|
11
|
+
// Registry
|
|
12
|
+
export { RegistryService, RegistryServiceLayer, } from "./registry";
|
|
13
|
+
// Execution
|
|
14
|
+
export { JobExecutionService, JobExecutionServiceLayer, } from "./execution";
|
|
15
|
+
// Cleanup
|
|
16
|
+
export { CleanupService, CleanupServiceLayer, } from "./cleanup";
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Combined Layer
|
|
19
|
+
// =============================================================================
|
|
20
|
+
import { MetadataServiceLayer } from "./metadata";
|
|
21
|
+
import { AlarmServiceLayer } from "./alarm";
|
|
22
|
+
import { IdempotencyServiceLayer } from "./idempotency";
|
|
23
|
+
/**
|
|
24
|
+
* Combined layer for all runtime services.
|
|
25
|
+
*
|
|
26
|
+
* Requires: StorageAdapter, SchedulerAdapter, RuntimeAdapter
|
|
27
|
+
* Provides: MetadataService, AlarmService, IdempotencyService
|
|
28
|
+
*
|
|
29
|
+
* Note: EntityStateService is NOT included because it's a factory function
|
|
30
|
+
* that creates instances per-schema, not a singleton service.
|
|
31
|
+
*/
|
|
32
|
+
export const RuntimeServicesLayer = Layer.mergeAll(MetadataServiceLayer, AlarmServiceLayer, IdempotencyServiceLayer);
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B,WAAW;AACX,OAAO,EACL,eAAe,EACf,oBAAoB,GAKrB,MAAM,YAAY,CAAC;AAEpB,eAAe;AACf,OAAO,EACL,wBAAwB,GAEzB,MAAM,gBAAgB,CAAC;AAExB,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAsB,MAAM,SAAS,CAAC;AAE9E,cAAc;AACd,OAAO,EACL,kBAAkB,EAClB,uBAAuB,GAExB,MAAM,eAAe,CAAC;AAEvB,WAAW;AACX,OAAO,EACL,eAAe,EACf,oBAAoB,GAErB,MAAM,YAAY,CAAC;AAEpB,YAAY;AACZ,OAAO,EACL,mBAAmB,EACnB,wBAAwB,GAMzB,MAAM,aAAa,CAAC;AAErB,UAAU;AACV,OAAO,EACL,cAAc,EACd,mBAAmB,GAEpB,MAAM,WAAW,CAAC;AAEnB,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,QAAQ,CAChD,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,CACxB,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from "effect";
|
|
2
|
+
import { StorageAdapter, RuntimeAdapter, type StorageError } from "@durable-effect/core";
|
|
3
|
+
/**
|
|
4
|
+
* Job types supported by the runtime.
|
|
5
|
+
*/
|
|
6
|
+
export type JobType = "continuous" | "debounce" | "workerPool" | "task";
|
|
7
|
+
/**
|
|
8
|
+
* Status of a job instance.
|
|
9
|
+
*/
|
|
10
|
+
export type JobStatus = "initializing" | "running" | "stopped" | "terminated";
|
|
11
|
+
/**
|
|
12
|
+
* Metadata stored for every job instance.
|
|
13
|
+
*/
|
|
14
|
+
export interface JobMetadata {
|
|
15
|
+
readonly type: JobType;
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly status: JobStatus;
|
|
18
|
+
readonly createdAt: number;
|
|
19
|
+
readonly updatedAt: number;
|
|
20
|
+
/** Reason for stopping/terminating (if applicable) */
|
|
21
|
+
readonly stopReason?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* MetadataService manages job instance metadata.
|
|
25
|
+
*
|
|
26
|
+
* Every job instance stores metadata that identifies:
|
|
27
|
+
* - What type of job it is (continuous, debounce, workerPool)
|
|
28
|
+
* - What named job definition it belongs to
|
|
29
|
+
* - Current status
|
|
30
|
+
* - Timestamps
|
|
31
|
+
*/
|
|
32
|
+
export interface MetadataServiceI {
|
|
33
|
+
/**
|
|
34
|
+
* Initialize metadata for a new job instance.
|
|
35
|
+
*/
|
|
36
|
+
readonly initialize: (type: JobType, name: string) => Effect.Effect<void, StorageError>;
|
|
37
|
+
/**
|
|
38
|
+
* Get metadata for this instance.
|
|
39
|
+
* Returns undefined if instance was never initialized.
|
|
40
|
+
*/
|
|
41
|
+
readonly get: () => Effect.Effect<JobMetadata | undefined, StorageError>;
|
|
42
|
+
/**
|
|
43
|
+
* Update the status of this instance.
|
|
44
|
+
* No-op if instance doesn't exist.
|
|
45
|
+
*/
|
|
46
|
+
readonly updateStatus: (status: JobStatus) => Effect.Effect<void, StorageError>;
|
|
47
|
+
/**
|
|
48
|
+
* Delete metadata for this instance.
|
|
49
|
+
* Called during purge.
|
|
50
|
+
* Returns true if key existed, false otherwise.
|
|
51
|
+
*/
|
|
52
|
+
readonly delete: () => Effect.Effect<boolean, StorageError>;
|
|
53
|
+
/**
|
|
54
|
+
* Set the stop reason for this instance.
|
|
55
|
+
* Used when terminating/stopping with a reason.
|
|
56
|
+
*/
|
|
57
|
+
readonly setStopReason: (reason: string | undefined) => Effect.Effect<void, StorageError>;
|
|
58
|
+
}
|
|
59
|
+
declare const MetadataService_base: Context.TagClass<MetadataService, "@durable-effect/jobs/MetadataService", MetadataServiceI>;
|
|
60
|
+
export declare class MetadataService extends MetadataService_base {
|
|
61
|
+
}
|
|
62
|
+
export declare const MetadataServiceLayer: Layer.Layer<MetadataService, never, RuntimeAdapter | StorageAdapter>;
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/services/metadata.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EACL,cAAc,EACd,cAAc,EACd,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAO9B;;GAEG;AACH,MAAM,MAAM,OAAO,GAAG,YAAY,GAAG,UAAU,GAAG,YAAY,GAAG,MAAM,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,cAAc,GACd,SAAS,GACT,SAAS,GACT,YAAY,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,CACnB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,MAAM,KACT,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,GAAG,SAAS,EAAE,YAAY,CAAC,CAAC;IAEzE;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,CACrB,MAAM,EAAE,SAAS,KACd,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAEvC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAE5D;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,CACtB,MAAM,EAAE,MAAM,GAAG,SAAS,KACvB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;CACxC;;AAMD,qBAAa,eAAgB,SAAQ,oBAEC;CAAG;AAMzC,eAAO,MAAM,oBAAoB,sEAqDhC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// packages/jobs/src/services/metadata.ts
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import { StorageAdapter, RuntimeAdapter, } from "@durable-effect/core";
|
|
4
|
+
import { KEYS } from "../storage-keys";
|
|
5
|
+
// =============================================================================
|
|
6
|
+
// Service Tag
|
|
7
|
+
// =============================================================================
|
|
8
|
+
export class MetadataService extends Context.Tag("@durable-effect/jobs/MetadataService")() {
|
|
9
|
+
}
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// Implementation
|
|
12
|
+
// =============================================================================
|
|
13
|
+
export const MetadataServiceLayer = Layer.effect(MetadataService, Effect.gen(function* () {
|
|
14
|
+
const storage = yield* StorageAdapter;
|
|
15
|
+
const runtime = yield* RuntimeAdapter;
|
|
16
|
+
return {
|
|
17
|
+
initialize: (type, name) => Effect.gen(function* () {
|
|
18
|
+
const now = yield* runtime.now();
|
|
19
|
+
const metadata = {
|
|
20
|
+
type,
|
|
21
|
+
name,
|
|
22
|
+
status: "initializing",
|
|
23
|
+
createdAt: now,
|
|
24
|
+
updatedAt: now,
|
|
25
|
+
};
|
|
26
|
+
yield* storage.put(KEYS.META, metadata);
|
|
27
|
+
}),
|
|
28
|
+
get: () => storage.get(KEYS.META),
|
|
29
|
+
updateStatus: (status) => Effect.gen(function* () {
|
|
30
|
+
const current = yield* storage.get(KEYS.META);
|
|
31
|
+
if (!current)
|
|
32
|
+
return;
|
|
33
|
+
const now = yield* runtime.now();
|
|
34
|
+
const updated = {
|
|
35
|
+
...current,
|
|
36
|
+
status,
|
|
37
|
+
updatedAt: now,
|
|
38
|
+
};
|
|
39
|
+
yield* storage.put(KEYS.META, updated);
|
|
40
|
+
}),
|
|
41
|
+
delete: () => storage.delete(KEYS.META),
|
|
42
|
+
setStopReason: (reason) => Effect.gen(function* () {
|
|
43
|
+
const current = yield* storage.get(KEYS.META);
|
|
44
|
+
if (!current)
|
|
45
|
+
return;
|
|
46
|
+
const now = yield* runtime.now();
|
|
47
|
+
const updated = {
|
|
48
|
+
...current,
|
|
49
|
+
stopReason: reason,
|
|
50
|
+
updatedAt: now,
|
|
51
|
+
};
|
|
52
|
+
yield* storage.put(KEYS.META, updated);
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
}));
|
|
56
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/services/metadata.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EACL,cAAc,EACd,cAAc,GAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAqFvC,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF,MAAM,OAAO,eAAgB,SAAQ,OAAO,CAAC,GAAG,CAC9C,sCAAsC,CACvC,EAAqC;CAAG;AAEzC,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAEhF,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,MAAM,CAC9C,eAAe,EACf,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,cAAc,CAAC;IAEtC,OAAO;QACL,UAAU,EAAE,CAAC,IAAa,EAAE,IAAY,EAAE,EAAE,CAC1C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAgB;gBAC5B,IAAI;gBACJ,IAAI;gBACJ,MAAM,EAAE,cAAc;gBACtB,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,GAAG;aACf,CAAC;YACF,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC,CAAC;QAEJ,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAc,IAAI,CAAC,IAAI,CAAC;QAE9C,YAAY,EAAE,CAAC,MAAiB,EAAE,EAAE,CAClC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAc,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,OAAO;gBAAE,OAAO;YAErB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,OAAO,GAAgB;gBAC3B,GAAG,OAAO;gBACV,MAAM;gBACN,SAAS,EAAE,GAAG;aACf,CAAC;YACF,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC;QAEJ,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QAEvC,aAAa,EAAE,CAAC,MAA0B,EAAE,EAAE,CAC5C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAc,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,OAAO;gBAAE,OAAO;YAErB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACjC,MAAM,OAAO,GAAgB;gBAC3B,GAAG,OAAO;gBACV,UAAU,EAAE,MAAM;gBAClB,SAAS,EAAE,GAAG;aACf,CAAC;YACF,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACzC,CAAC,CAAC;KACL,CAAC;AACJ,CAAC,CAAC,CACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Context, Layer } from "effect";
|
|
2
|
+
import type { RuntimeJobRegistry } from "../registry/typed";
|
|
3
|
+
/**
|
|
4
|
+
* Registry service provides access to job definitions.
|
|
5
|
+
*
|
|
6
|
+
* This is injected via Layer so handlers can look up definitions.
|
|
7
|
+
*/
|
|
8
|
+
export interface RegistryServiceI {
|
|
9
|
+
readonly registry: RuntimeJobRegistry;
|
|
10
|
+
}
|
|
11
|
+
declare const RegistryService_base: Context.TagClass<RegistryService, "@durable-effect/jobs/RegistryService", RegistryServiceI>;
|
|
12
|
+
export declare class RegistryService extends RegistryService_base {
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a Registry service layer from a registry.
|
|
16
|
+
*/
|
|
17
|
+
export declare function RegistryServiceLayer(registry: RuntimeJobRegistry): Layer.Layer<RegistryService>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/services/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAM5D;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;CACvC;;AAMD,qBAAa,eAAgB,SAAQ,oBAEC;CAAG;AAMzC;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,kBAAkB,GAC3B,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAE9B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// packages/jobs/src/services/registry.ts
|
|
2
|
+
import { Context, Layer } from "effect";
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Service Tag
|
|
5
|
+
// =============================================================================
|
|
6
|
+
export class RegistryService extends Context.Tag("@durable-effect/jobs/RegistryService")() {
|
|
7
|
+
}
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Layer Factory
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Create a Registry service layer from a registry.
|
|
13
|
+
*/
|
|
14
|
+
export function RegistryServiceLayer(registry) {
|
|
15
|
+
return Layer.succeed(RegistryService, { registry });
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/services/registry.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAgBxC,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF,MAAM,OAAO,eAAgB,SAAQ,OAAO,CAAC,GAAG,CAC9C,sCAAsC,CACvC,EAAqC;CAAG;AAEzC,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA4B;IAE5B,OAAO,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized storage key constants for all jobs.
|
|
3
|
+
* Using a single namespace ensures no collisions and makes debugging easier.
|
|
4
|
+
*/
|
|
5
|
+
export declare const KEYS: {
|
|
6
|
+
readonly META: "meta";
|
|
7
|
+
readonly STATE: "state";
|
|
8
|
+
readonly CONTINUOUS: {
|
|
9
|
+
readonly RUN_COUNT: "cont:runCount";
|
|
10
|
+
readonly LAST_EXECUTED_AT: "cont:lastAt";
|
|
11
|
+
};
|
|
12
|
+
readonly DEBOUNCE: {
|
|
13
|
+
readonly EVENT_COUNT: "deb:count";
|
|
14
|
+
readonly STARTED_AT: "deb:startedAt";
|
|
15
|
+
};
|
|
16
|
+
readonly WORKER_POOL: {
|
|
17
|
+
readonly EVENTS: "wp:events:";
|
|
18
|
+
readonly PENDING: "wp:pending";
|
|
19
|
+
readonly PROCESSED: "wp:processed";
|
|
20
|
+
readonly CURRENT: "wp:current";
|
|
21
|
+
readonly ATTEMPT: "wp:attempt";
|
|
22
|
+
readonly PAUSED: "wp:paused";
|
|
23
|
+
};
|
|
24
|
+
readonly TASK: {
|
|
25
|
+
readonly EVENT_COUNT: "task:eventCount";
|
|
26
|
+
readonly EXECUTE_COUNT: "task:execCount";
|
|
27
|
+
readonly CREATED_AT: "task:createdAt";
|
|
28
|
+
readonly SCHEDULED_AT: "task:scheduledAt";
|
|
29
|
+
};
|
|
30
|
+
readonly IDEMPOTENCY: "idem:";
|
|
31
|
+
readonly RETRY: {
|
|
32
|
+
readonly ATTEMPT: "retry:attempt";
|
|
33
|
+
readonly STARTED_AT: "retry:startedAt";
|
|
34
|
+
readonly LAST_ERROR: "retry:lastError";
|
|
35
|
+
readonly SCHEDULED_AT: "retry:scheduledAt";
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=storage-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-keys.d.ts","sourceRoot":"","sources":["../src/storage-keys.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CP,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// packages/jobs/src/storage-keys.ts
|
|
2
|
+
/**
|
|
3
|
+
* Centralized storage key constants for all jobs.
|
|
4
|
+
* Using a single namespace ensures no collisions and makes debugging easier.
|
|
5
|
+
*/
|
|
6
|
+
export const KEYS = {
|
|
7
|
+
// Metadata (all jobs)
|
|
8
|
+
META: "meta",
|
|
9
|
+
// User state (schema-validated)
|
|
10
|
+
STATE: "state",
|
|
11
|
+
// Continuous-specific
|
|
12
|
+
CONTINUOUS: {
|
|
13
|
+
RUN_COUNT: "cont:runCount",
|
|
14
|
+
LAST_EXECUTED_AT: "cont:lastAt",
|
|
15
|
+
},
|
|
16
|
+
// Debounce-specific
|
|
17
|
+
DEBOUNCE: {
|
|
18
|
+
EVENT_COUNT: "deb:count",
|
|
19
|
+
STARTED_AT: "deb:startedAt",
|
|
20
|
+
},
|
|
21
|
+
// WorkerPool-specific
|
|
22
|
+
WORKER_POOL: {
|
|
23
|
+
EVENTS: "wp:events:", // prefix: wp:events:{eventId}
|
|
24
|
+
PENDING: "wp:pending", // array of pending event IDs
|
|
25
|
+
PROCESSED: "wp:processed",
|
|
26
|
+
CURRENT: "wp:current",
|
|
27
|
+
ATTEMPT: "wp:attempt",
|
|
28
|
+
PAUSED: "wp:paused",
|
|
29
|
+
},
|
|
30
|
+
// Task-specific
|
|
31
|
+
TASK: {
|
|
32
|
+
EVENT_COUNT: "task:eventCount",
|
|
33
|
+
EXECUTE_COUNT: "task:execCount",
|
|
34
|
+
CREATED_AT: "task:createdAt",
|
|
35
|
+
SCHEDULED_AT: "task:scheduledAt",
|
|
36
|
+
},
|
|
37
|
+
// Idempotency
|
|
38
|
+
IDEMPOTENCY: "idem:", // prefix: idem:{eventId}
|
|
39
|
+
// Retry tracking (shared across job types)
|
|
40
|
+
RETRY: {
|
|
41
|
+
ATTEMPT: "retry:attempt", // Current attempt (1-indexed)
|
|
42
|
+
STARTED_AT: "retry:startedAt", // When retry sequence started
|
|
43
|
+
LAST_ERROR: "retry:lastError", // Serialized last error
|
|
44
|
+
SCHEDULED_AT: "retry:scheduledAt", // When next retry is scheduled
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=storage-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-keys.js","sourceRoot":"","sources":["../src/storage-keys.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,sBAAsB;IACtB,IAAI,EAAE,MAAM;IAEZ,gCAAgC;IAChC,KAAK,EAAE,OAAO;IAEd,sBAAsB;IACtB,UAAU,EAAE;QACV,SAAS,EAAE,eAAe;QAC1B,gBAAgB,EAAE,aAAa;KAChC;IAED,oBAAoB;IACpB,QAAQ,EAAE;QACR,WAAW,EAAE,WAAW;QACxB,UAAU,EAAE,eAAe;KAC5B;IAED,sBAAsB;IACtB,WAAW,EAAE;QACX,MAAM,EAAE,YAAY,EAAE,8BAA8B;QACpD,OAAO,EAAE,YAAY,EAAE,6BAA6B;QACpD,SAAS,EAAE,cAAc;QACzB,OAAO,EAAE,YAAY;QACrB,OAAO,EAAE,YAAY;QACrB,MAAM,EAAE,WAAW;KACpB;IAED,gBAAgB;IAChB,IAAI,EAAE;QACJ,WAAW,EAAE,iBAAiB;QAC9B,aAAa,EAAE,gBAAgB;QAC/B,UAAU,EAAE,gBAAgB;QAC5B,YAAY,EAAE,kBAAkB;KACjC;IAED,cAAc;IACd,WAAW,EAAE,OAAO,EAAE,yBAAyB;IAE/C,2CAA2C;IAC3C,KAAK,EAAE;QACL,OAAO,EAAE,eAAe,EAAE,8BAA8B;QACxD,UAAU,EAAE,iBAAiB,EAAE,8BAA8B;QAC7D,UAAU,EAAE,iBAAiB,EAAE,wBAAwB;QACvD,YAAY,EAAE,mBAAmB,EAAE,+BAA+B;KACnE;CACO,CAAC"}
|