effect-mq 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -17
- package/dist/Flow.d.ts +381 -0
- package/dist/Flow.d.ts.map +1 -0
- package/dist/Flow.js +340 -0
- package/dist/Flow.js.map +1 -0
- package/dist/Job.d.ts +31 -6
- package/dist/Job.d.ts.map +1 -1
- package/dist/Job.js +16 -2
- package/dist/Job.js.map +1 -1
- package/dist/JobStore.d.ts +312 -10
- package/dist/JobStore.d.ts.map +1 -1
- package/dist/JobStore.js.map +1 -1
- package/dist/MemoryJobStore.d.ts.map +1 -1
- package/dist/MemoryJobStore.js +334 -7
- package/dist/MemoryJobStore.js.map +1 -1
- package/dist/Metrics.d.ts +31 -0
- package/dist/Metrics.d.ts.map +1 -1
- package/dist/Metrics.js +39 -0
- package/dist/Metrics.js.map +1 -1
- package/dist/Worker.d.ts +120 -11
- package/dist/Worker.d.ts.map +1 -1
- package/dist/Worker.js +452 -26
- package/dist/Worker.js.map +1 -1
- package/dist/drizzle-postgres/DrizzleJobStore.d.ts +19 -1
- package/dist/drizzle-postgres/DrizzleJobStore.d.ts.map +1 -1
- package/dist/drizzle-postgres/DrizzleJobStore.js +653 -77
- package/dist/drizzle-postgres/DrizzleJobStore.js.map +1 -1
- package/dist/drizzle-postgres/schema.d.ts +293 -3
- package/dist/drizzle-postgres/schema.d.ts.map +1 -1
- package/dist/drizzle-postgres/schema.js +66 -1
- package/dist/drizzle-postgres/schema.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/redis/RedisJobStore.d.ts.map +1 -1
- package/dist/redis/RedisJobStore.js +219 -18
- package/dist/redis/RedisJobStore.js.map +1 -1
- package/dist/redis/scripts.d.ts +117 -10
- package/dist/redis/scripts.d.ts.map +1 -1
- package/dist/redis/scripts.js +492 -25
- package/dist/redis/scripts.js.map +1 -1
- package/dist/testing/conformance.d.ts +6 -0
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +728 -1
- package/dist/testing/conformance.js.map +1 -1
- package/package.json +1 -1
- package/src/Flow.ts +778 -0
- package/src/Job.ts +35 -11
- package/src/JobStore.ts +339 -9
- package/src/MemoryJobStore.ts +370 -7
- package/src/Metrics.ts +43 -0
- package/src/Worker.ts +726 -37
- package/src/drizzle-postgres/DrizzleJobStore.ts +817 -78
- package/src/drizzle-postgres/schema.ts +92 -0
- package/src/index.ts +8 -0
- package/src/redis/RedisJobStore.ts +289 -8
- package/src/redis/scripts.ts +524 -24
- package/src/testing/conformance.ts +945 -1
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@ const producer = Effect.gen(function*() {
|
|
|
51
51
|
// 3. Run. Workers are layers — deploy them in the same process or across
|
|
52
52
|
// machines against shared storage.
|
|
53
53
|
const RunnerLive = SendEmail.toLayer(
|
|
54
|
-
(payload
|
|
54
|
+
(payload) => Effect.map(Worker.CurrentJob, ({ jobId }) => `message-${jobId}`),
|
|
55
55
|
{ concurrency: 5 }
|
|
56
56
|
).pipe(
|
|
57
57
|
Layer.provideMerge(Worker.layer()),
|
|
@@ -144,6 +144,49 @@ occurrences, missed slots collapse into one run (the next sweep enqueues the
|
|
|
144
144
|
overdue slot once, then advances past `now`). Options mirror `enqueue`:
|
|
145
145
|
`metadata`, `priority`, `attempts`, `backoff`, `keep`, `timeout`.
|
|
146
146
|
|
|
147
|
+
## Parent-child flows
|
|
148
|
+
|
|
149
|
+
A flow fans a parent job out into N children, parks the parent until every
|
|
150
|
+
child settles, then resumes it with their typed results. Children can live
|
|
151
|
+
on a **different store** than the parent (a cron parent in Postgres fanning
|
|
152
|
+
out 10k idempotent sends into Redis, collecting the outcomes back):
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import { Flow } from "effect-mq"
|
|
156
|
+
|
|
157
|
+
const DigestFlow = Flow.make("daily-digest", {
|
|
158
|
+
parent: SendDigest, // Postgres
|
|
159
|
+
children: [SendEmail], // Redis
|
|
160
|
+
onChildFailure: "continue" // or "fail": first failure settles the flow
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// The parent worker runs two phases (requires parent AND child stores):
|
|
164
|
+
const DigestWorker = DigestFlow.toLayer({
|
|
165
|
+
fanOut: (payload) =>
|
|
166
|
+
Effect.map(Users.active, (users) =>
|
|
167
|
+
Flow.children(SendEmail, users.map((user) => ({
|
|
168
|
+
key: user.id, // unique in the flow = idempotency
|
|
169
|
+
payload: { userId: user.id }
|
|
170
|
+
})))),
|
|
171
|
+
collect: (payload, results) =>
|
|
172
|
+
Effect.succeed({ sent: results.counts.completed, failed: results.counts.failed })
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
// Workers that run the children declare the flow so their relay can push
|
|
176
|
+
// results to the parent store the moment each child acks:
|
|
177
|
+
Worker.layer({ store: EmailStore, flows: [DigestFlow] })
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The parent's store owns the flow (manifest, per-child results, outcome
|
|
181
|
+
counters), so "settle exactly once" is single-store atomic. Cross-store,
|
|
182
|
+
every terminal child transition appends its report to the child store's
|
|
183
|
+
**outbox** in the same atomic operation; worker relays push those in
|
|
184
|
+
batches (children keep completing through parent-store outages) and a
|
|
185
|
+
reconciliation sweeper repairs anything the push path misses, from storage
|
|
186
|
+
alone. Flows nest (a child can be another flow's parent), and `collect`
|
|
187
|
+
reads results as plain `counts`, materialized buckets, or a paged `Stream`.
|
|
188
|
+
Docs: [Parent-child flows](https://www.effect-mq.com/guide/flows).
|
|
189
|
+
|
|
147
190
|
## Timeouts, cancellation, and unrecoverable errors
|
|
148
191
|
|
|
149
192
|
Because handlers are Effect fibers, the runtime can *actually stop them* —
|
|
@@ -357,16 +400,26 @@ migrations** — no library-run DDL, no parallel migration system:
|
|
|
357
400
|
|
|
358
401
|
```ts
|
|
359
402
|
// db/schema.ts
|
|
360
|
-
import {
|
|
403
|
+
import {
|
|
404
|
+
mqDedupe,
|
|
405
|
+
mqFlowChildren,
|
|
406
|
+
mqFlowOutbox,
|
|
407
|
+
mqJobAttempts,
|
|
408
|
+
mqJobs,
|
|
409
|
+
mqQueueControl,
|
|
410
|
+
mqSchedules
|
|
411
|
+
} from "effect-mq/drizzle-postgres"
|
|
361
412
|
|
|
362
413
|
// The `name` column is typed to your job tags (derived, not hand-written):
|
|
363
414
|
type JobNames = typeof GenerateInvoice._tag | typeof SendEmail._tag
|
|
364
415
|
|
|
365
|
-
export const jobs = mqJobs<JobNames>()
|
|
366
|
-
export const jobAttempts = mqJobAttempts(jobs)
|
|
367
|
-
export const jobSchedules = mqSchedules()
|
|
368
|
-
export const jobQueues = mqQueueControl()
|
|
369
|
-
export const jobDedupe = mqDedupe()
|
|
416
|
+
export const jobs = mqJobs<JobNames>() // default table: effect_mq_jobs
|
|
417
|
+
export const jobAttempts = mqJobAttempts(jobs) // default: effect_mq_job_attempts
|
|
418
|
+
export const jobSchedules = mqSchedules() // default: effect_mq_schedules
|
|
419
|
+
export const jobQueues = mqQueueControl() // default: effect_mq_queue_control
|
|
420
|
+
export const jobDedupe = mqDedupe() // default: effect_mq_dedupe
|
|
421
|
+
export const jobFlowChildren = mqFlowChildren() // default: effect_mq_flow_children
|
|
422
|
+
export const jobFlowOutbox = mqFlowOutbox() // default: effect_mq_flow_outbox
|
|
370
423
|
```
|
|
371
424
|
|
|
372
425
|
Need more indexes (the built-ins cover claiming, listing, metadata
|
|
@@ -390,7 +443,7 @@ table; at enqueue the store fills each extended column from the job's
|
|
|
390
443
|
`metadata: (payload) => ...` is your creation-time hook), NULL when absent:
|
|
391
444
|
|
|
392
445
|
```ts
|
|
393
|
-
class
|
|
446
|
+
class SyncPayments extends Job.make("sync-payments", {
|
|
394
447
|
payload: { companyId: Schema.String, objectId: Schema.String },
|
|
395
448
|
metadata: ({ companyId, objectId }) => ({ companyId, objectId })
|
|
396
449
|
}) {}
|
|
@@ -427,14 +480,24 @@ When a future effect-mq version changes the layout, the factory changes and
|
|
|
427
480
|
import { DrizzleJobStore } from "effect-mq/drizzle-postgres"
|
|
428
481
|
import { PgClient } from "@effect/sql-pg"
|
|
429
482
|
import { Layer, Redacted } from "effect"
|
|
430
|
-
import {
|
|
483
|
+
import {
|
|
484
|
+
jobAttempts,
|
|
485
|
+
jobDedupe,
|
|
486
|
+
jobFlowChildren,
|
|
487
|
+
jobFlowOutbox,
|
|
488
|
+
jobQueues,
|
|
489
|
+
jobs,
|
|
490
|
+
jobSchedules
|
|
491
|
+
} from "./db/schema.ts"
|
|
431
492
|
|
|
432
493
|
const JobStoreLive = DrizzleJobStore.layer({
|
|
433
494
|
jobs,
|
|
434
495
|
attempts: jobAttempts,
|
|
435
496
|
schedules: jobSchedules,
|
|
436
497
|
queues: jobQueues,
|
|
437
|
-
dedupe: jobDedupe
|
|
498
|
+
dedupe: jobDedupe,
|
|
499
|
+
flowChildren: jobFlowChildren,
|
|
500
|
+
flowOutbox: jobFlowOutbox
|
|
438
501
|
}).pipe(
|
|
439
502
|
Layer.provide(PgClient.layer({ url: Redacted.make(process.env.DATABASE_URL!) }))
|
|
440
503
|
)
|
|
@@ -593,6 +656,9 @@ ledger), `retry`, `cancel`, `cancelByKey` (by dedup key, idempotent),
|
|
|
593
656
|
| `queueMetricsInterval` | off | sample `store.counts()` per queue into the depth gauge |
|
|
594
657
|
| `handlerSpanName` | `` `${name}.run` `` | name of the span wrapping each handler run |
|
|
595
658
|
| `traceLinking` | `auto` | parent for immediate jobs, causal link for delayed ones (`parent`/`link`/`none` force a mode) |
|
|
659
|
+
| `onJobFailure` | — | callback after each failed run is acked; runs isolated |
|
|
660
|
+
| `flows` | — | flows whose children this worker runs (lets its relay push results) |
|
|
661
|
+
| `flowSweepInterval` | 30s | flow sweeper cadence + the relay's fallback drain cadence |
|
|
596
662
|
| `id` | random | identifier used in lock tokens |
|
|
597
663
|
|
|
598
664
|
**Store construction** — every driver accepts `idGenerator`, `historyTtl`,
|
|
@@ -629,12 +695,14 @@ plain Effect, so it works with any test runner.
|
|
|
629
695
|
|
|
630
696
|
## Writing a storage driver
|
|
631
697
|
|
|
632
|
-
Implement the `JobStore` service (one atomic seam: `enqueue`,
|
|
633
|
-
`release`, `extendLocks`, `recoverStalled`, `awaitWake`,
|
|
634
|
-
`getAttempts`, `list`, `retry`, `counts`, `remove`, `cancel`,
|
|
635
|
-
`pause`/`resume`/`pausedQueues`, `cancelByDedupe`,
|
|
636
|
-
`upsertSchedule`/`removeSchedule`/`listSchedules`/`dueSchedules
|
|
637
|
-
and
|
|
698
|
+
Implement the `JobStore` service (one atomic seam: `enqueue`/`enqueueMany`,
|
|
699
|
+
`claim`, `ack`, `release`, `extendLocks`, `recoverStalled`, `awaitWake`,
|
|
700
|
+
`getJob`, `getAttempts`, `list`, `retry`, `counts`, `remove`, `cancel`,
|
|
701
|
+
`promote`, `pause`/`resume`/`pausedQueues`, `cancelByDedupe`, the schedule
|
|
702
|
+
ops `upsertSchedule`/`removeSchedule`/`listSchedules`/`dueSchedules`/
|
|
703
|
+
`tickSchedule`/`advanceSchedule`, and the flow ops `recordChildResults`/
|
|
704
|
+
`listChildResults`/`flowSweepWork`/`markChildrenCascaded`/`peekOutbox`/
|
|
705
|
+
`deleteOutbox`) and run the conformance suite against it:
|
|
638
706
|
|
|
639
707
|
```ts
|
|
640
708
|
import { jobStoreConformance } from "effect-mq/testing"
|
|
@@ -652,7 +720,7 @@ suite in this repo runs the same conformance tests against a real database.
|
|
|
652
720
|
|
|
653
721
|
Next up: drizzle schema customization (column renames, native id and
|
|
654
722
|
timestamp column types, a typed queue registry), a cross-process event
|
|
655
|
-
stream, and
|
|
723
|
+
stream, and global queue concurrency/rate limits. Full prioritized list:
|
|
656
724
|
[ROADMAP.md](https://github.com/TeamWarp/effect-mq/blob/main/ROADMAP.md);
|
|
657
725
|
release history:
|
|
658
726
|
[CHANGELOG.md](https://github.com/TeamWarp/effect-mq/blob/main/CHANGELOG.md).
|
package/dist/Flow.d.ts
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-store parent-child flows.
|
|
3
|
+
*
|
|
4
|
+
* A flow's PARENT job fans out N child jobs, parks in `waiting-children`
|
|
5
|
+
* until every child settles, then resumes with their typed results. The
|
|
6
|
+
* children may live on a **different store** than the parent — a
|
|
7
|
+
* cron-scheduled parent in Postgres can fan out thousands of idempotent
|
|
8
|
+
* sends into Redis and collect the outcomes back in Postgres.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* const DigestFlow = Flow.make("daily-digest", {
|
|
12
|
+
* parent: SendDigest, // a Job bound to the Postgres store
|
|
13
|
+
* children: [SendEmail], // Jobs, each bound to their own store
|
|
14
|
+
* onChildFailure: "continue" // default; "fail" settles on first failure
|
|
15
|
+
* })
|
|
16
|
+
*
|
|
17
|
+
* // the parent worker runs both phases (requires the parent AND child stores)
|
|
18
|
+
* const DigestWorker = DigestFlow.toLayer({
|
|
19
|
+
* fanOut: (payload) =>
|
|
20
|
+
* Effect.gen(function*() {
|
|
21
|
+
* const users = yield* Users.active
|
|
22
|
+
* return Flow.children(SendEmail, users.map((user) => ({
|
|
23
|
+
* key: user.id,
|
|
24
|
+
* payload: { userId: user.id }
|
|
25
|
+
* })))
|
|
26
|
+
* }),
|
|
27
|
+
* collect: (payload, results) =>
|
|
28
|
+
* Effect.succeed({ sent: results.counts.completed, failed: results.counts.failed })
|
|
29
|
+
* // or: yield* results.all (materialized buckets), results.stream (paged)
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* // workers that run the CHILDREN list the flow so results push instantly:
|
|
33
|
+
* // Worker.layer({ store: EmailStore, flows: [DigestFlow] })
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* Architecture (see `designs/parent-child-flows.md`): the parent's store
|
|
37
|
+
* owns the flow — child manifest, per-child results, outcome counters — so
|
|
38
|
+
* "the flow settles exactly once" is single-store atomic. Cross-store needs
|
|
39
|
+
* only two at-least-once idempotent mechanisms: every terminal child
|
|
40
|
+
* transition atomically appends its report to the CHILD store's outbox,
|
|
41
|
+
* which worker relays *push* into the parent store in batches (children
|
|
42
|
+
* keep completing even while the parent store is down); and the parent
|
|
43
|
+
* worker's flow sweeper *reconciles* from child-store state (repairs
|
|
44
|
+
* everything the push path can miss: crashes mid-enqueue, dropped outbox
|
|
45
|
+
* entries, children terminal on stores no relay reaches).
|
|
46
|
+
*
|
|
47
|
+
* Flows nest: a child may itself be another flow's parent, reporting upward
|
|
48
|
+
* through the same machinery when it settles. Depth is capped (8) so a
|
|
49
|
+
* cyclic definition surfaces as an unrecoverable failure instead of an
|
|
50
|
+
* unbounded chain.
|
|
51
|
+
*
|
|
52
|
+
* Flow children bypass the child definition's `idempotencyKey`/`dedupe` —
|
|
53
|
+
* the child `key` (unique within the flow) IS the idempotency mechanism,
|
|
54
|
+
* carried in the deterministic job id. Handlers should be idempotent, as
|
|
55
|
+
* everywhere under at-least-once.
|
|
56
|
+
*
|
|
57
|
+
* @since 0.6.0
|
|
58
|
+
*/
|
|
59
|
+
import { Cause, Context, Effect, Layer, Schema, Stream } from "effect";
|
|
60
|
+
import { type AnyStructSchema, type JobOptions, type ResolvedDefaults } from "./Job.ts";
|
|
61
|
+
import { JobId, type QueueName, type Service as StoreService } from "./JobStore.ts";
|
|
62
|
+
import { type CurrentJob, type RegisterOptions, Worker } from "./Worker.ts";
|
|
63
|
+
/**
|
|
64
|
+
* The structural view of a `Job.make` class a flow needs from its members.
|
|
65
|
+
* Contravariant callback members are typed with `never` parameters so every
|
|
66
|
+
* concrete job satisfies the constraint; the runtime only ever passes a
|
|
67
|
+
* job's own payload back into them.
|
|
68
|
+
*
|
|
69
|
+
* @since 0.6.0
|
|
70
|
+
*/
|
|
71
|
+
export interface MemberJob {
|
|
72
|
+
readonly _tag: string;
|
|
73
|
+
readonly queue: QueueName;
|
|
74
|
+
readonly store: Context.Key<any, StoreService>;
|
|
75
|
+
readonly payloadSchema: AnyStructSchema;
|
|
76
|
+
readonly payloadJsonSchema: Schema.Top;
|
|
77
|
+
readonly successSchema: Schema.Top;
|
|
78
|
+
readonly errorSchema: Schema.Top;
|
|
79
|
+
readonly exitSchema: Schema.Top;
|
|
80
|
+
readonly defaults: ResolvedDefaults;
|
|
81
|
+
readonly metadata: ((payload: never) => Readonly<Record<string, string>>) | undefined;
|
|
82
|
+
readonly retryable: ((error: never) => boolean) | undefined;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The structural view of the parent job: a `MemberJob` plus the producer
|
|
86
|
+
* surface the flow delegates (`Flow.enqueue` IS the parent's `enqueue`).
|
|
87
|
+
*
|
|
88
|
+
* @since 0.6.0
|
|
89
|
+
*/
|
|
90
|
+
export interface ParentJob extends MemberJob {
|
|
91
|
+
readonly enqueue: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
92
|
+
readonly enqueueMany: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
93
|
+
readonly execute: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
94
|
+
readonly poll: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
95
|
+
readonly attempts: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
96
|
+
readonly awaitResult: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
97
|
+
readonly retry: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
98
|
+
readonly cancel: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
99
|
+
readonly promote: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
100
|
+
readonly schedule: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
101
|
+
readonly unschedule: (...args: ReadonlyArray<never>) => Effect.Effect<any, any, any>;
|
|
102
|
+
}
|
|
103
|
+
type NameOf<J> = J extends {
|
|
104
|
+
readonly _tag: infer N extends string;
|
|
105
|
+
} ? N : never;
|
|
106
|
+
type PayloadMakeIn<J> = J extends {
|
|
107
|
+
readonly payloadSchema: infer P extends AnyStructSchema;
|
|
108
|
+
} ? P["~type.make.in"] : never;
|
|
109
|
+
type PayloadType<J> = J extends {
|
|
110
|
+
readonly payloadSchema: infer P extends AnyStructSchema;
|
|
111
|
+
} ? P["Type"] : never;
|
|
112
|
+
type PayloadEncodingServices<J> = J extends {
|
|
113
|
+
readonly payloadSchema: infer P extends AnyStructSchema;
|
|
114
|
+
} ? P["EncodingServices"] : never;
|
|
115
|
+
type SuccessValue<J> = J extends {
|
|
116
|
+
readonly successSchema: infer S extends Schema.Top;
|
|
117
|
+
} ? S["Type"] : never;
|
|
118
|
+
type SuccessDecodingServices<J> = J extends {
|
|
119
|
+
readonly successSchema: infer S extends Schema.Top;
|
|
120
|
+
} ? S["DecodingServices"] : never;
|
|
121
|
+
type SuccessEncodingServices<J> = J extends {
|
|
122
|
+
readonly successSchema: infer S extends Schema.Top;
|
|
123
|
+
} ? S["EncodingServices"] : never;
|
|
124
|
+
type ErrorValue<J> = J extends {
|
|
125
|
+
readonly errorSchema: infer E extends Schema.Top;
|
|
126
|
+
} ? E["Type"] : never;
|
|
127
|
+
type ErrorDecodingServices<J> = J extends {
|
|
128
|
+
readonly errorSchema: infer E extends Schema.Top;
|
|
129
|
+
} ? E["DecodingServices"] : never;
|
|
130
|
+
type ErrorEncodingServices<J> = J extends {
|
|
131
|
+
readonly errorSchema: infer E extends Schema.Top;
|
|
132
|
+
} ? E["EncodingServices"] : never;
|
|
133
|
+
type PayloadDecodingServices<J> = J extends {
|
|
134
|
+
readonly payloadSchema: infer P extends AnyStructSchema;
|
|
135
|
+
} ? P["DecodingServices"] : never;
|
|
136
|
+
/**
|
|
137
|
+
* The StoreIds of a flow's members — what `toLayer` requires so the parent
|
|
138
|
+
* worker is guaranteed able to reconcile and cascade into every child store.
|
|
139
|
+
*
|
|
140
|
+
* @since 0.6.0
|
|
141
|
+
*/
|
|
142
|
+
export type MemberStores<J> = J extends {
|
|
143
|
+
readonly store: Context.Key<infer Id, StoreService>;
|
|
144
|
+
} ? Id : never;
|
|
145
|
+
/**
|
|
146
|
+
* Per-child options accepted by `Flow.children` items — the shared
|
|
147
|
+
* `JobOptions` minus `delay` (flow children run immediately), plus
|
|
148
|
+
* `metadata` merged over the child definition's callback.
|
|
149
|
+
*
|
|
150
|
+
* @since 0.6.0
|
|
151
|
+
*/
|
|
152
|
+
export type ChildOptions = Omit<JobOptions, "delay"> & {
|
|
153
|
+
readonly metadata?: Readonly<Record<string, string>> | undefined;
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* One child to fan out: its flow-unique `key` (the idempotency mechanism —
|
|
157
|
+
* re-runs of `fanOut` re-produce the same child, never a second one), the
|
|
158
|
+
* payload, and optional per-child options.
|
|
159
|
+
*
|
|
160
|
+
* @since 0.6.0
|
|
161
|
+
*/
|
|
162
|
+
export interface ChildItem<PayloadInput> {
|
|
163
|
+
readonly key: string;
|
|
164
|
+
readonly payload: PayloadInput;
|
|
165
|
+
readonly options?: ChildOptions | undefined;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* A group of children of one member type, built by `Flow.children`. A
|
|
169
|
+
* `fanOut` handler returns one group or an array of them.
|
|
170
|
+
*
|
|
171
|
+
* @since 0.6.0
|
|
172
|
+
*/
|
|
173
|
+
export interface ChildGroup<out J extends MemberJob = MemberJob> {
|
|
174
|
+
readonly job: J;
|
|
175
|
+
readonly items: ReadonlyArray<ChildItem<PayloadMakeIn<J>>>;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* A naked-parameter distribution of `ChildGroup` over a union of members,
|
|
179
|
+
* so a group literal must pair a member's `job` with THAT member's payloads
|
|
180
|
+
* (the undistributed `ChildGroup<A | B>` would accept `A`'s job with `B`'s
|
|
181
|
+
* items).
|
|
182
|
+
*
|
|
183
|
+
* @since 0.6.0
|
|
184
|
+
*/
|
|
185
|
+
export type GroupsOf<J> = J extends MemberJob ? ChildGroup<J> : never;
|
|
186
|
+
/**
|
|
187
|
+
* What `fanOut` returns: children of any of the flow's member types.
|
|
188
|
+
*
|
|
189
|
+
* @since 0.6.0
|
|
190
|
+
*/
|
|
191
|
+
export type ChildrenInput<J extends MemberJob> = GroupsOf<J> | ReadonlyArray<GroupsOf<J>>;
|
|
192
|
+
/**
|
|
193
|
+
* The deterministic id of a flow child. Every component is an arbitrary
|
|
194
|
+
* string (store keys, ids, and child keys may all contain "/"), so the two
|
|
195
|
+
* variable-length boundaries are pinned by a length prefix — distinct
|
|
196
|
+
* (storeKey, flowId, childKey) triples can never alias.
|
|
197
|
+
*
|
|
198
|
+
* @internal
|
|
199
|
+
*/
|
|
200
|
+
export declare const childJobId: (parentStoreKey: string, flowId: string, childKey: string) => string;
|
|
201
|
+
/**
|
|
202
|
+
* Declare children of one member type. Payloads are validated through the
|
|
203
|
+
* child's schema when the specs are built; duplicate keys (across ALL
|
|
204
|
+
* groups) fail the fan-out unrecoverably.
|
|
205
|
+
*
|
|
206
|
+
* @since 0.6.0
|
|
207
|
+
*/
|
|
208
|
+
export declare const children: <J extends MemberJob>(job: J, items: ReadonlyArray<ChildItem<PayloadMakeIn<J>>>) => ChildGroup<J>;
|
|
209
|
+
/**
|
|
210
|
+
* A child that completed, with its decoded success value.
|
|
211
|
+
*
|
|
212
|
+
* @since 0.6.0
|
|
213
|
+
*/
|
|
214
|
+
export interface CompletedChild<Name extends string, A> {
|
|
215
|
+
readonly key: string;
|
|
216
|
+
readonly name: Name;
|
|
217
|
+
readonly value: A;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* A child that failed terminally. `cause` carries the decoded typed failure
|
|
221
|
+
* — or a die for store-side failures that never produced an exit (stall
|
|
222
|
+
* exhaustion, a nested parent's fail-fast settle).
|
|
223
|
+
*
|
|
224
|
+
* @since 0.6.0
|
|
225
|
+
*/
|
|
226
|
+
export interface FailedChild<Name extends string, E> {
|
|
227
|
+
readonly key: string;
|
|
228
|
+
readonly name: Name;
|
|
229
|
+
readonly cause: Cause.Cause<E>;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* A child that was cancelled — directly in its store, or by a flow settle
|
|
233
|
+
* (fail-fast, or a cancel of the waiting parent).
|
|
234
|
+
*
|
|
235
|
+
* @since 0.6.0
|
|
236
|
+
*/
|
|
237
|
+
export interface CancelledChild<Name extends string> {
|
|
238
|
+
readonly key: string;
|
|
239
|
+
readonly name: Name;
|
|
240
|
+
}
|
|
241
|
+
type CompletedOf<J> = J extends MemberJob ? CompletedChild<NameOf<J>, SuccessValue<J>> : never;
|
|
242
|
+
type FailedOf<J> = J extends MemberJob ? FailedChild<NameOf<J>, ErrorValue<J>> : never;
|
|
243
|
+
type CancelledOf<J> = J extends MemberJob ? CancelledChild<NameOf<J>> : never;
|
|
244
|
+
/**
|
|
245
|
+
* Per-outcome tallies, read straight off the parent's persisted `FlowState`
|
|
246
|
+
* — no dependency-row reads. When `collect` runs, `pending` is 0.
|
|
247
|
+
*
|
|
248
|
+
* @since 0.6.0
|
|
249
|
+
*/
|
|
250
|
+
export interface ChildCounts {
|
|
251
|
+
readonly pending: number;
|
|
252
|
+
readonly completed: number;
|
|
253
|
+
readonly failed: number;
|
|
254
|
+
readonly cancelled: number;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* One settled child, discriminated by `outcome` (and by `name` across
|
|
258
|
+
* member types), decoded through its member's schemas.
|
|
259
|
+
*
|
|
260
|
+
* @since 0.6.0
|
|
261
|
+
*/
|
|
262
|
+
export type SettledChild<J extends MemberJob> = ({
|
|
263
|
+
readonly outcome: "completed";
|
|
264
|
+
} & CompletedOf<J>) | ({
|
|
265
|
+
readonly outcome: "failed";
|
|
266
|
+
} & FailedOf<J>) | ({
|
|
267
|
+
readonly outcome: "cancelled";
|
|
268
|
+
} & CancelledOf<J>);
|
|
269
|
+
/**
|
|
270
|
+
* Every settled child, materialized into outcome buckets.
|
|
271
|
+
*
|
|
272
|
+
* @since 0.6.0
|
|
273
|
+
*/
|
|
274
|
+
export interface SettledChildren<J extends MemberJob> {
|
|
275
|
+
readonly completed: ReadonlyArray<Extract<SettledChild<J>, {
|
|
276
|
+
readonly outcome: "completed";
|
|
277
|
+
}>>;
|
|
278
|
+
readonly failed: ReadonlyArray<Extract<SettledChild<J>, {
|
|
279
|
+
readonly outcome: "failed";
|
|
280
|
+
}>>;
|
|
281
|
+
readonly cancelled: ReadonlyArray<Extract<SettledChild<J>, {
|
|
282
|
+
readonly outcome: "cancelled";
|
|
283
|
+
}>>;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* What `collect` (and `Flow.childResults`) receives: `counts` for free,
|
|
287
|
+
* `all` to materialize the outcome buckets (one array — fine into the
|
|
288
|
+
* tens of thousands), and `stream` to fold huge flows one page at a time.
|
|
289
|
+
*
|
|
290
|
+
* @since 0.6.0
|
|
291
|
+
*/
|
|
292
|
+
export interface ChildResults<J extends MemberJob> {
|
|
293
|
+
readonly counts: ChildCounts;
|
|
294
|
+
readonly all: Effect.Effect<SettledChildren<J>>;
|
|
295
|
+
readonly stream: Stream.Stream<SettledChild<J>>;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* The two-phase flow handler. `fanOut` runs once per flow (persisted phase
|
|
299
|
+
* dispatch — a resumed parent can never fan out twice) and returns the
|
|
300
|
+
* children; `collect` runs after every child settled, with their results.
|
|
301
|
+
* Both draw on the PARENT's attempt budget: a failing `fanOut` retries
|
|
302
|
+
* against it until the manifest lands, a failing `collect` retries with
|
|
303
|
+
* what remains.
|
|
304
|
+
*
|
|
305
|
+
* @since 0.6.0
|
|
306
|
+
*/
|
|
307
|
+
export interface FlowHandlers<Parent extends ParentJob, Children extends ReadonlyArray<MemberJob>, R1, R2> {
|
|
308
|
+
readonly fanOut: (payload: PayloadType<Parent>) => Effect.Effect<ChildrenInput<Children[number]>, ErrorValue<Parent>, R1>;
|
|
309
|
+
readonly collect: (payload: PayloadType<Parent>, results: ChildResults<Children[number]>) => Effect.Effect<SuccessValue<Parent>, ErrorValue<Parent>, R2>;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* A flow definition. The producer surface (`enqueue`, `execute`, `poll`,
|
|
313
|
+
* `awaitResult`, `schedule`, ...) IS the parent job's — a flow parent is a
|
|
314
|
+
* real job row in the parent store, and a scheduled parent needs no flow
|
|
315
|
+
* awareness in its schedule row.
|
|
316
|
+
*
|
|
317
|
+
* Note on fail-fast (`onChildFailure: "fail"`): the first failed child
|
|
318
|
+
* settles the parent terminally `failed` store-side (`failedReason` names
|
|
319
|
+
* the child; there is no parent exit, so `awaitResult` dies — like stall
|
|
320
|
+
* exhaustion) and the remaining children are cancelled. The failed child's
|
|
321
|
+
* own exit stays inspectable via `childResults`. An admin `retry` of the
|
|
322
|
+
* parent re-enters `collect` with the mixed results.
|
|
323
|
+
*
|
|
324
|
+
* @since 0.6.0
|
|
325
|
+
*/
|
|
326
|
+
export interface Flow<Name extends string, Parent extends ParentJob, Children extends ReadonlyArray<MemberJob>> {
|
|
327
|
+
readonly name: Name;
|
|
328
|
+
readonly parent: Parent;
|
|
329
|
+
readonly children: Children;
|
|
330
|
+
/** True when `onChildFailure` is `"fail"`. */
|
|
331
|
+
readonly failFast: boolean;
|
|
332
|
+
readonly enqueue: Parent["enqueue"];
|
|
333
|
+
readonly enqueueMany: Parent["enqueueMany"];
|
|
334
|
+
readonly execute: Parent["execute"];
|
|
335
|
+
readonly poll: Parent["poll"];
|
|
336
|
+
readonly attempts: Parent["attempts"];
|
|
337
|
+
readonly awaitResult: Parent["awaitResult"];
|
|
338
|
+
readonly retry: Parent["retry"];
|
|
339
|
+
readonly cancel: Parent["cancel"];
|
|
340
|
+
readonly promote: Parent["promote"];
|
|
341
|
+
readonly schedule: Parent["schedule"];
|
|
342
|
+
readonly unschedule: Parent["unschedule"];
|
|
343
|
+
/**
|
|
344
|
+
* The flow's recorded child results, in any parent state: live `counts`
|
|
345
|
+
* plus the `all`/`stream` accessors — children still pending are absent
|
|
346
|
+
* from both.
|
|
347
|
+
*/
|
|
348
|
+
readonly childResults: (flowId: JobId) => Effect.Effect<ChildResults<Children[number]>, never, MemberStores<Parent> | SuccessDecodingServices<Children[number]> | ErrorDecodingServices<Children[number]>>;
|
|
349
|
+
/**
|
|
350
|
+
* Register the parent's two phases on a worker (bound to the parent's
|
|
351
|
+
* store). Requires every member store — this is what makes the parent
|
|
352
|
+
* worker the one process guaranteed capable of reconciling and cascading
|
|
353
|
+
* across the whole flow.
|
|
354
|
+
*/
|
|
355
|
+
readonly toLayer: <R1, R2>(handlers: FlowHandlers<Parent, Children, R1, R2>, options?: RegisterOptions | undefined) => Layer.Layer<never, never, Worker | Exclude<R1, CurrentJob> | Exclude<R2, CurrentJob> | MemberStores<Parent> | MemberStores<Children[number]> | PayloadDecodingServices<Parent> | SuccessEncodingServices<Parent> | ErrorEncodingServices<Parent> | PayloadEncodingServices<Children[number]> | SuccessDecodingServices<Children[number]> | ErrorDecodingServices<Children[number]>>;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Define a flow over existing job definitions.
|
|
359
|
+
*
|
|
360
|
+
* Throws (synchronously, at definition time) on duplicate child names or a
|
|
361
|
+
* parent listed among its own children (direct self-recursion). Nesting
|
|
362
|
+
* across DIFFERENT flows is supported — see the module docs.
|
|
363
|
+
*
|
|
364
|
+
* @since 0.6.0
|
|
365
|
+
*/
|
|
366
|
+
export declare const make: <const Name extends string, Parent extends ParentJob, const Children extends ReadonlyArray<MemberJob>>(name: Name, options: {
|
|
367
|
+
/** The parent job: its store owns the flow. */
|
|
368
|
+
readonly parent: Parent;
|
|
369
|
+
/** The closed set of member definitions `fanOut` may produce. */
|
|
370
|
+
readonly children: Children;
|
|
371
|
+
/**
|
|
372
|
+
* What a failed child does to the flow:
|
|
373
|
+
* - `"continue"` (default): every child settles; `collect` sees the
|
|
374
|
+
* failures in `results.failed`.
|
|
375
|
+
* - `"fail"`: the first failed child settles the parent as `failed`
|
|
376
|
+
* and cancels the remaining children (see the `Flow` docs).
|
|
377
|
+
*/
|
|
378
|
+
readonly onChildFailure?: "continue" | "fail" | undefined;
|
|
379
|
+
}) => Flow<Name, Parent, Children>;
|
|
380
|
+
export {};
|
|
381
|
+
//# sourceMappingURL=Flow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Flow.d.ts","sourceRoot":"","sources":["../src/Flow.ts"],"names":[],"mappings":"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"}
|