Effect.ts: Absence as First-Class
Concurrency • Lesson 15 of 51
15. Real-World Pipeline
Combining all the HOWs: retry, timeout, parallel, fallback
Code Example
const pipeline = Effect.gen(function* () {
// HOW: Retry + timeout
const data = yield* fetchData().pipe(
Effect.timeout("5 seconds"),
Effect.retry({ times: 3 })
);
// HOW: Parallel processing
const [validated, enriched] = yield* Effect.all([
validate(data),
enrich(data)
]);
// HOW: Fallback on error
yield* save(validated, enriched).pipe(
Effect.catchAll(() =>
logError().pipe(Effect.as(undefined))
)
);
return { success: true };
});
Interactive Example
const fetchData = () => Effect.succeed({ raw: 'data' });
const validate = (data) => Effect.succeed({ ...data, validated: true });
const enrich = (data) => Effect.succeed({ ...data, enriched: true });
const save = (v, e) => Effect.succeed('saved');
const pipeline = Effect.gen(function* () {
const data = yield* fetchData().pipe(
Effect.timeout('5 seconds'),
Effect.retry({ times: 3 })
);
const [validated, enriched] = yield* Effect.all([validate(data), enrich(data)]);
yield* save(validated, enriched).pipe(
Effect.catchAll(() => Effect.succeed(undefined))
);
return { success: true };
});
const result = await Effect.runPromise(pipeline);
return `${"Real-world pipeline!
Fetched (with timeout}${retry)
Validated & enriched (parallel)
Saved (with fallback)
Result: "}${JSON.stringify(result)}
Multiple HOWs composed!`;
Explanation
Real-world: composing multiple HOWs for complex absence resolution.
Every step is about unavailability:
- data: unavailable until fetched (with timeout & retry HOWs)
- validated/enriched: unavailable until processed (parallel HOW)
- save result: might be unavailable (fallback HOW)
No assumptions anywhere! Each absence has its own resolution strategy. This is absence-first architecture!
Part 15 of 51 in the Effect.ts Absence Modeling series