• v2.2.3 7e99fc6d70

    fix(runner): fix audio task infinite loop and semaphore race
    Some checks failed
    Release / Check ui (push) Successful in 22s
    Release / Test backend (push) Successful in 33s
    Release / Docker / backend (push) Failing after 30s
    Release / Docker / caddy (push) Successful in 1m9s
    Release / Docker / ui (push) Successful in 1m34s
    Release / Docker / runner (push) Failing after 1m15s
    Release / Gitea Release (push) Has been skipped

    kamil released this 2026-03-25 15:09:52 +05:00 | -247 commits to main since this release

    Two bugs caused audio tasks to loop endlessly:

    1. 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.

    2. 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