Effect.ts: Absence as First-Class
State Management • Lesson 34 of 51
34. Semaphore - Limited Access Permits
Control HOW MANY concurrent operations can access resources
Code Example
const program = Effect.gen(function* () {
// Only 3 concurrent database connections
const semaphore = yield* Semaphore.make(3);
const processUser = (id: string) =>
semaphore.withPermits(1)(
Effect.gen(function* () {
yield* Console.log(`Processing ${id}`);
yield* Effect.sleep("1 second");
return `Done: ${id}`;
})
);
// Process 10 users - but only 3 at a time!
yield* Effect.all(
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i =>
processUser(`user${i}`)
),
{ concurrency: "unbounded" } // Still limited by semaphore!
);
});
Interactive Example
return `Semaphore concept!
Semaphore.make(2)
→ Only 2 permits available
4 tasks request permits:
- Task 1 & 2: Get permits (run)
- Task 3 & 4: Wait for permits
When Task 1 finishes:
- Releases permit
- Task 3 gets it (runs)
Max concurrent: 2 (limited by semaphore)
Resource limiting!
Note: Semaphore requires Effect runtime
setup not available in browser demo.`;
Explanation
Semaphore: resource availability is limited (permits are absent).
Traditional approach: hope you don't overload resources. Semaphore types limited resource availability:
- 3 permits available = only 3 resources exist
- 4th request: access is absent (must wait)
- No assumptions about resource availability
- withPermits: acquire absent permit, auto-release
Absence-first resource control: permits are absent until available!
Part 34 of 51 in the Effect.ts Absence Modeling series