Monorepo for Tangled tangled.org

Workflow timeout counts time spent waiting for a slot #4650

Closed bunny.fae.mom
Closed opened by bunny.fae.mom

Current behaviour #

A workflow's timeout clock starts before it waits for a slot, so time spent queued counts against the workflow timeout. On a busy spindle a workflow can be killed as timeout without ever running for long: on ci.klbr.net a test.yml waited 39 minutes behind a 40-minute job and timed out a minute after it started.

In spindle/engine/engine.go, context.WithTimeout(wfCtx, workflowTimeout) is created at the top of the per-workflow goroutine. The quota reservation (qm.Acquire(wfCtx, …)) and the slot wait (AcquireWorkflowSlot(wfCtx, …, Wait)) both run under that context afterwards. The engine already tells the two apart in its log: the workflow finished line has wait_seconds and run_seconds.

Change #

Start the timeout once the slot is held, so the budget covers running time only. User cancellation must keep working while a workflow is queued, so the cancel context should stay outside the timeout. Waiting could get its own, separate bound if unbounded queueing is a concern.

Done when #

A workflow that queues longer than the workflow timeout, then runs for less than it, finishes successfully. A test with a slotter that blocks past the timeout before granting the slot shows this.


Found while running a self-hosted spindle (ci.klbr.net). Issue found and reported by Opus 5.5.

Sign up or Sign in to add to the discussion.