PAIPAI

Queueing And Wakeups

How busy threads, queued items, and realtime wakeups interact.

PAI runs one active run per thread. Additional work is queued.

active run exists
  -> new send creates a queued run and queued item
  -> current run finishes or blocks
  -> runner claims the next queued item

The caller still uses the same API:

const run = await thread.send("Follow up on the report");

If the message queues, the returned RunHandle represents the accepted work with status "queued". It may wait before execution begins.

Why Wakeups Exist

After a message is sent or queued, some worker must notice it.

Wakeups reduce latency:

message/run queued -> wake runner
state committed -> wake watchers
generation chunk -> wake live clients

Wakeups are not correctness. If a wakeup is lost, polling and claim loops still recover because the durable queued item remains in storage.

Race Avoidance

The runtime plans send/queue policy and the store applies its root, run, queue, and lease changes atomically. Avoid designs where one request checks "busy" and another separately writes queue state without a complete ThreadVersion precondition.

The invariant is:

queued items, run status, and the run lease are committed together under one ThreadVersion compare-and-swap

On this page