08 / DATA
threading
A fan-out group that is collected first and joined at wait, a queue drained by one consumer for work that must not run on the request's own task, and a queue that keeps only the newest pending item so a burst collapses to its last value.
WHERE IT SITS
INTERFACE
struct TaskRunner[T]structA queue drained by one consumer: push hands work over and returns, run is the loop that takes it. What a service uses when the work must not run on the request's own task — a write-behind, a slow notification.
fn[T] TaskRunner::new() -> TaskRunner[T]itemA runner with an unbounded queue.
async fn[T] TaskRunner::push(self : TaskRunner[T], item : T) -> UnititemHand one item to the consumer, waiting if the queue is bounded and full.
fn[T] TaskRunner::try_push(self : TaskRunner[T], item : T) -> BoolitemTry to hand one item over without waiting; false when the queue is full or already closed.
async fn[T] TaskRunner::run( self : TaskRunner[T], handle : async (T) -> Unit) -> UnititemDrain the queue, handing each item to handle, until the runner is closed. A handler that raises stops the loop and the failure reaches whoever is waiting for the service.
fn[T] TaskRunner::close(self : TaskRunner[T]) -> UnititemStop accepting work and wake the consumer so it can finish.
struct RoutineGroupstructA set of tasks that are started together and joined together. Bodies are collected first and run at wait, which is what makes the group usable while the tasks they depend on are still being decided: a fan-out whose width comes from the data does not have to know that width up front.
fn RoutineGroup::new() -> RoutineGroupfnA group with nothing in it.
fn RoutineGroup::run(self : RoutineGroup, body : async () -> Unit) -> UnitfnAdd a body to the group. The bodies run concurrently when wait is called.
fn RoutineGroup::len(self : RoutineGroup) -> Int32fnHow many bodies are waiting.
async fn RoutineGroup::wait(self : RoutineGroup) -> UnititemRun every body concurrently and return when all of them have finished. A body that raises cancels the others and the failure reaches the caller.
struct StableRunner[T]structA runner that keeps only the newest pending item: pushing while the consumer is busy replaces what it will take next, so a burst collapses to its last value. A service uses it for work that is idempotent and worth doing only once — a configuration reload, a cache refresh, a re-index triggered by a write.
fn[T] StableRunner::new() -> StableRunner[T]itemA stable runner with nothing pending. The queue holds one item and drops the oldest when a newer one arrives, so a producer never waits and never queues more than one turn of work.
async fn[T] StableRunner::push(self : StableRunner[T], item : T) -> UnititemMake item the pending one, replacing whatever was pending. The queue holds one item and discards the older one, so this never waits for the consumer.
async fn[T] StableRunner::run( self : StableRunner[T], handle : async (T) -> Unit) -> UnititemTake the pending item and hand it to handle, one at a time, until the runner is closed.
fn[T] StableRunner::close(self : StableRunner[T]) -> UnititemStop accepting work and wake the consumer so it can finish.