Effect.ts: Absence as First-Class
Resources • Lesson 22 of 51
22. Fibers - Lightweight Threads
Fibers are virtual threads for concurrent execution. They model CONCURRENT absence resolution.
Code Example
// Start two operations concurrently
const fiber1 = Effect.fork(fetchFromAPI1());
const fiber2 = Effect.fork(fetchFromAPI2());
// Fibers run in background (values being resolved)
// We have handles to potentially-absent values!
const program = Effect.gen(function* () {
// Do other work while they run...
yield* doOtherStuff();
// Join: wait for absent values to arrive
const result1 = yield* Fiber.join(fiber1);
const result2 = yield* Fiber.join(fiber2);
return combineResults(result1, result2);
});
// Or interrupt if we don't need them anymore:
fiber1.interrupt(); // Stop waiting for that value
Interactive Example
const { Fiber } = await import('effect');
const task1 = Effect.gen(function* () {
yield* Effect.sleep('50 millis');
return 'Task 1 done';
});
const task2 = Effect.gen(function* () {
yield* Effect.sleep('30 millis');
return 'Task 2 done';
});
const start = Date.now();
const fiber1 = Effect.runFork(task1);
const fiber2 = Effect.runFork(task2);
const result1 = await Effect.runPromise(Fiber.join(fiber1));
const result2 = await Effect.runPromise(Fiber.join(fiber2));
const elapsed = Date.now() - start;
return `Fibers!
Task 1: ${result1} (50ms)
Task 2: ${result2} (30ms)
Total time: ${elapsed}ms
Concurrent execution!`;
Explanation
Fibers: handles to concurrent absence resolution.
Traditional approach: threads are OS-level, heavyweight. Fiber types lightweight concurrent absence:
- API1 data is unavailable (fork starts resolving)
- API2 data is unavailable (fork starts resolving)
- Fibers = handles to "being-resolved" absence
- No assumptions about completion order
Absence-first concurrency: explicit handles to in-flight absence resolution!
Part 22 of 51 in the Effect.ts Absence Modeling series