Effect.ts: Absence as First-Class

ConcurrencyLesson 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