GenStage-based executor providing demand-driven dispatch with back-pressure.
Uses a GenStage Producer + Consumer pool architecture. The Producer buffers work items and Consumers pull them on demand, providing natural back-pressure that prevents the Worker from overwhelming available compute.
Each consumer processes one work item at a time (max_demand: 1). The number
of consumers controls the concurrency level. Work items that arrive when all
consumers are busy are buffered in the Producer until demand is available.
Options
:max_demand— number of concurrent consumers (default:System.schedulers_online()):buffer_size— producer event buffer size (default::infinity)
Architecture
Worker (caller)
│ dispatch/3 → cast to Producer
▼
GenStage.Producer (buffers {handle, work_fn, caller} events)
│
├──────────────────┤
▼ ▼
Consumer 1 Consumer N
(execute work_fn) (execute work_fn)
│ │
└──── send {handle, result} / {:DOWN, handle, ...} to caller ────┘Message Contract
Preserves the standard Executor message contract:
{handle, result}— sent to caller on successful completion{:DOWN, handle, :process, pid, reason}— sent to caller on failure
Failures are caught inside the consumer via try/catch, so individual work
item failures do not crash the consumer process.