fix: make asynq consumer actually claim and heartbeat translation tasks
All checks were successful
Release / Check ui (push) Successful in 27s
Release / Test backend (push) Successful in 43s
Release / Docker / caddy (push) Successful in 1m3s
Release / Docker / ui (push) Successful in 1m58s
Release / Docker / runner (push) Successful in 3m23s
Release / Docker / backend (push) Successful in 4m26s
Release / Gitea Release (push) Successful in 13s
All checks were successful
Release / Check ui (push) Successful in 27s
Release / Test backend (push) Successful in 43s
Release / Docker / caddy (push) Successful in 1m3s
Release / Docker / ui (push) Successful in 1m58s
Release / Docker / runner (push) Successful in 3m23s
Release / Docker / backend (push) Successful in 4m26s
Release / Gitea Release (push) Successful in 13s
ClaimNextTranslationTask and HeartbeatTask were no-ops in the asynq Consumer, so translation tasks created in PocketBase were never picked up by the runner. Translation tasks live in PocketBase (not Redis), so they must be claimed/heartbeated via the underlying pb consumer. ReapStaleTasks is also delegated so stale translation tasks get reset. Also removes the LibreTranslate healthcheck from homelab/runner docker-compose.yml and relaxes depends_on to service_started — the healthcheck was blocking runner startup until models loaded (~2 min) and the models are already pre-downloaded in the volume.
This commit is contained in:
@@ -10,14 +10,13 @@ import (
|
|||||||
|
|
||||||
// Consumer wraps the PocketBase-backed Consumer for result write-back only.
|
// Consumer wraps the PocketBase-backed Consumer for result write-back only.
|
||||||
//
|
//
|
||||||
// When using Asynq, the runner no longer polls for work — Asynq delivers
|
// When using Asynq, the runner no longer polls for scrape/audio work — Asynq
|
||||||
// tasks via the ServeMux handlers. The only Consumer operations the handlers
|
// delivers those tasks via the ServeMux handlers. However translation tasks
|
||||||
// need are:
|
// live in PocketBase (not Redis), so ClaimNextTranslationTask and HeartbeatTask
|
||||||
// - FinishAudioTask / FinishScrapeTask — write result back to PocketBase
|
// still delegate to the underlying PocketBase consumer.
|
||||||
// - FailTask — mark PocketBase record as failed
|
|
||||||
//
|
//
|
||||||
// ClaimNextAudioTask, ClaimNextScrapeTask, HeartbeatTask, and ReapStaleTasks
|
// ClaimNextAudioTask, ClaimNextScrapeTask are no-ops here because Asynq owns
|
||||||
// are all no-ops here because Asynq owns those responsibilities.
|
// those responsibilities.
|
||||||
type Consumer struct {
|
type Consumer struct {
|
||||||
pb taskqueue.Consumer // underlying PocketBase consumer (for write-back)
|
pb taskqueue.Consumer // underlying PocketBase consumer (for write-back)
|
||||||
}
|
}
|
||||||
@@ -55,10 +54,18 @@ func (c *Consumer) ClaimNextAudioTask(_ context.Context, _ string) (domain.Audio
|
|||||||
return domain.AudioTask{}, false, nil
|
return domain.AudioTask{}, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Consumer) ClaimNextTranslationTask(_ context.Context, _ string) (domain.TranslationTask, bool, error) {
|
// ClaimNextTranslationTask delegates to PocketBase because translation tasks
|
||||||
return domain.TranslationTask{}, false, nil
|
// are stored in PocketBase (not Redis/Asynq) and must still be polled directly.
|
||||||
|
func (c *Consumer) ClaimNextTranslationTask(ctx context.Context, workerID string) (domain.TranslationTask, bool, error) {
|
||||||
|
return c.pb.ClaimNextTranslationTask(ctx, workerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Consumer) HeartbeatTask(_ context.Context, _ string) error { return nil }
|
func (c *Consumer) HeartbeatTask(ctx context.Context, id string) error {
|
||||||
|
return c.pb.HeartbeatTask(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Consumer) ReapStaleTasks(_ context.Context, _ time.Duration) (int, error) { return 0, nil }
|
// ReapStaleTasks delegates to PocketBase so stale translation tasks are reset
|
||||||
|
// to pending and can be reclaimed.
|
||||||
|
func (c *Consumer) ReapStaleTasks(ctx context.Context, staleAfter time.Duration) (int, error) {
|
||||||
|
return c.pb.ReapStaleTasks(ctx, staleAfter)
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,20 +28,13 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- libretranslate_models:/home/libretranslate/.local/share/argos-translate
|
- libretranslate_models:/home/libretranslate/.local/share/argos-translate
|
||||||
- libretranslate_db:/app/db
|
- libretranslate_db:/app/db
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "python3", "-c", "import urllib.request,sys; urllib.request.urlopen('http://localhost:5000/languages'); sys.exit(0)"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 5
|
|
||||||
start_period: 120s
|
|
||||||
|
|
||||||
runner:
|
runner:
|
||||||
image: kalekber/libnovel-runner:latest
|
image: kalekber/libnovel-runner:latest
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
stop_grace_period: 135s
|
stop_grace_period: 135s
|
||||||
depends_on:
|
depends_on:
|
||||||
libretranslate:
|
- libretranslate
|
||||||
condition: service_healthy
|
|
||||||
environment:
|
environment:
|
||||||
# ── PocketBase ──────────────────────────────────────────────────────────
|
# ── PocketBase ──────────────────────────────────────────────────────────
|
||||||
POCKETBASE_URL: "https://pb.libnovel.cc"
|
POCKETBASE_URL: "https://pb.libnovel.cc"
|
||||||
|
|||||||
Reference in New Issue
Block a user