dista starts no machines. Whatever owns them (orca's ec2 runner, a shell
loop, a Kubernetes operator) reads the head's demand, dista status --json,
asks decide what to do, starts that many workers and drains the ones it
names with dista drain:
var d = Demand.parse(observer.status_json())
var got = decide(d, Policy(min_workers=0, max_workers=12), now, pending,
short_since)
# start got.start workers; drain each of got.drain; keep got.short_since
decide has no clock and no I/O: now is the provider's, in seconds, and
short_since, when the job first ran short of workers, comes back in the
decision for the next call. So it's tested on tables of demand over time.
Up: tasks ready with no free slot for up_after seconds start workers, at
most max_step at once, up to max_workers; with no worker at all, they
start at once. Workers asked for but not yet joined (pending) count as
there, so a slow boot isn't asked for twice.
Down: workers idle for idle_before_down seconds drain, fewest held bytes
first, down to min_workers, which may be 0. A worker hosting an actor
drains only with a checkpoint store to move it through; and the last worker
drains only once no task is left and it holds nothing, since its results
would have nowhere to go.