待ち行列への登録と状態表示を追加(新着からの登録、/queue、DATABASE_URL)

This commit is contained in:
2026-10-03 19:07:53 +09:00
parent a71b915c81
commit 4a02526e76
20 changed files with 1146 additions and 14 deletions
+19
View File
@@ -121,6 +121,17 @@ func (s *Store) Retry(ctx context.Context, id int64) error {
return transitionResult(tag.RowsAffected(), err)
}
// RetryEpisode はエピソード ID で失敗・中断されたジョブを再投入する。
func (s *Store) RetryEpisode(ctx context.Context, episodeID string) error {
tag, err := s.pool.Exec(ctx, `UPDATE download_jobs SET status='queued', phase=NULL,
downloaded_bytes=NULL, total_bytes=NULL, total_is_estimate=false, speed_bps=NULL,
eta_seconds=NULL, fragment_index=NULL, fragment_count=NULL, format_id=NULL,
error_kind=NULL, error_message=NULL, heartbeat_at=NULL, started_at=NULL,
finished_at=NULL, updated_at=now()
WHERE episode_id=$1 AND status IN ('failed','canceled')`, episodeID)
return transitionResult(tag.RowsAffected(), err)
}
// ClaimNext は最も古い未実行ジョブを同時 worker と重複せず取得する。
func (s *Store) ClaimNext(ctx context.Context) (Job, error) {
return scanJob(s.pool.QueryRow(ctx, `WITH next AS (
@@ -162,6 +173,14 @@ func (s *Store) Cancel(ctx context.Context, id int64) error {
return transitionResult(tag.RowsAffected(), err)
}
// CancelQueued は worker 未着手のジョブだけを取り消す。
func (s *Store) CancelQueued(ctx context.Context, id int64) error {
tag, err := s.pool.Exec(ctx, `UPDATE download_jobs SET status='canceled', phase=NULL,
error_kind='canceled', heartbeat_at=NULL, finished_at=now(), updated_at=now()
WHERE id=$1 AND status='queued'`, id)
return transitionResult(tag.RowsAffected(), err)
}
// RequeueStale は cutoff より前に heartbeat が止まった実行中ジョブを戻す。
func (s *Store) RequeueStale(ctx context.Context, cutoff time.Time) (int64, error) {
tag, err := s.pool.Exec(ctx, `UPDATE download_jobs SET status='queued', phase=NULL,