Effect.ts: Absence as First-Class
State Management • Lesson 32 of 51
32. Queue - Coordinating Absent Values
Queue stores values that producers create and consumers await
Code Example
const program = Effect.gen(function* () {
// Create queue - it's empty (values absent)
const queue = yield* Queue.bounded<string>(10);
// Consumer: wait for absent values
const consumer = Effect.gen(function* () {
while (true) {
// Suspends when queue is empty!
const item = yield* Queue.take(queue);
yield* Console.log(`Got: ${item}`);
}
});
// Producer: make values available
const producer = Effect.gen(function* () {
yield* Queue.offer(queue, "Task 1");
yield* Effect.sleep("100 millis");
yield* Queue.offer(queue, "Task 2");
});
// Run concurrently
yield* Effect.fork(consumer);
yield* producer;
});
Interactive Example
const { Queue } = await import('effect');
const program = Effect.gen(function* () {
const queue = yield* Queue.bounded(10);
yield* Queue.offer(queue, 'Task 1');
yield* Queue.offer(queue, 'Task 2');
yield* Queue.offer(queue, 'Task 3');
const item1 = yield* Queue.take(queue);
const item2 = yield* Queue.take(queue);
return [item1, item2];
});
const [t1, t2] = await Effect.runPromise(program);
return `Queue!
Offered: Task 1, Task 2, Task 3
Took: ${t1}, ${t2}
Remaining: 1 item
Producer/consumer coordination!`;
Explanation
Queue: coordinating temporal absence between fibers.
Traditional approach: shared arrays with locks (messy!). Queue types producer-consumer absence:
- Queue starts empty (all values absent)
- take: suspend until value becomes available
- offer: make value available to waiters
- No assumptions about producer/consumer speed
- Values flow from absent → available → absent again
Absence-first coordination: explicitly managing when values exist!
Part 32 of 51 in the Effect.ts Absence Modeling series