-
fix(runner): fix audio task infinite loop and semaphore race
Some checks failedRelease / Check ui (push) Successful in 22sRelease / Test backend (push) Successful in 33sRelease / Docker / backend (push) Failing after 30sRelease / Docker / caddy (push) Successful in 1m9sRelease / Docker / ui (push) Successful in 1m34sRelease / Docker / runner (push) Failing after 1m15sRelease / Gitea Release (push) Has been skippedreleased this
2026-03-25 15:09:52 +05:00 | -247 commits to main since this releaseTwo bugs caused audio tasks to loop endlessly:
-
claimRecord never set heartbeat_at — newly claimed tasks had
heartbeat_at=null, which matched the reaper's stale filter
(heartbeat_at=null || heartbeat_at<threshold). Tasks were reaped
and reset to pending within seconds of being claimed, before the
30s heartbeat goroutine had a chance to write a timestamp.
Fix: set heartbeat_at=now() in claimRecord alongside status=running. -
Audio semaphore was checked AFTER claiming the task. When the
semaphore was full the select/break only broke the inner select,
not the for loop — the code fell through and launched an uncapped
goroutine that blocked forever on <-audioSem drain. The task also
stayed status=running with no heartbeat, feeding bug #1.
Fix: pre-acquire a semaphore slot BEFORE claiming the task; release
it immediately if the queue is empty or claim fails.
Downloads
-