feat(publish): cancel stale queued publish tasks after queue timeout

Add CancelStaleQueuedPublishTasks to abort publish tasks that sit in the
queue past a configurable timeout (default 3 days) without being claimed by
a desktop client, so they no longer linger indefinitely as 'queued'. The
lease recovery worker runs the cleanup each cycle and reports a
cancelled_queued count; the timeout is configurable via job run config.
Aborted tasks carry a publish_queue_timeout error payload with a readable
Chinese duration, and the admin-web publish summary surfaces it as an
auto-cancelled queue-timeout message.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-08 22:56:37 +08:00
parent f1334aac80
commit 832d7f507d
5 changed files with 358 additions and 19 deletions
@@ -0,0 +1,42 @@
package scheduler
import (
"testing"
"time"
)
func TestPublishQueuedTaskTimeoutFromRunDefaultsToThreeDays(t *testing.T) {
t.Parallel()
got := publishQueuedTaskTimeoutFromRun(JobRunContext{})
if got != 3*24*time.Hour {
t.Fatalf("publishQueuedTaskTimeoutFromRun() = %s, want 72h", got)
}
}
func TestPublishQueuedTaskTimeoutFromRunReadsDurationConfig(t *testing.T) {
t.Parallel()
got := publishQueuedTaskTimeoutFromRun(JobRunContext{
Config: map[string]any{
"queued_task_timeout": "72h",
},
})
if got != 72*time.Hour {
t.Fatalf("publishQueuedTaskTimeoutFromRun(duration) = %s, want 72h", got)
}
}
func TestPublishQueuedTaskTimeoutFromRunReadsSecondsConfig(t *testing.T) {
t.Parallel()
got := publishQueuedTaskTimeoutFromRun(JobRunContext{
Config: map[string]any{
"queued_task_timeout": "72h",
"queued_task_timeout_seconds": 3600,
},
})
if got != time.Hour {
t.Fatalf("publishQueuedTaskTimeoutFromRun(seconds) = %s, want 1h", got)
}
}