feat(download): persist retry state and dead-letter
Retry count and queue status were in-memory only and lost on restart, so failed downloads could not be safely resumed and permanently-failed episodes silently blocked re-queueing via the episode-id unique index. - Add status + retry_count columns to DownloadQueueItem - Replace unique(episode_id) with unique(episode_id, status) so permanently_failed rows do not block new pending entries - Add PERMANENTLY_FAILED to DownloadStatus enum - Persist retry_count on each failure; mark permanently_failed once max_retries reached - QueueRepository reads status/retry_count from DB instead of defaulting to PENDING/0 - Stop double-incrementing retry_count in retry_failed_items; increment only happens in _process_download on failure Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -316,6 +316,7 @@ class DownloadQueueItem(Base, TimestampMixin):
|
||||
id: Primary key
|
||||
series_id: Foreign key to AnimeSeries
|
||||
episode_id: Foreign key to Episode
|
||||
status: Queue status (pending/downloading/completed/failed/permanently_failed)
|
||||
error_message: Error description if failed
|
||||
download_url: Provider download URL
|
||||
file_destination: Target file path
|
||||
@@ -347,12 +348,29 @@ class DownloadQueueItem(Base, TimestampMixin):
|
||||
index=True
|
||||
)
|
||||
|
||||
# Unique constraint to prevent duplicate pending queue items
|
||||
# An episode can only have one queue entry at a time
|
||||
# Status column to track queue item state
|
||||
# Allows distinguishing pending items from permanently failed ones
|
||||
status: Mapped[str] = mapped_column(
|
||||
String(50), nullable=False, default="pending",
|
||||
doc="Queue item status: pending, downloading, completed, failed, permanently_failed"
|
||||
)
|
||||
|
||||
# Retry count to track failed download attempts
|
||||
# Used to determine when to move item to permanently_failed
|
||||
retry_count: Mapped[int] = mapped_column(
|
||||
Integer, nullable=False, default=0,
|
||||
doc="Number of retry attempts for this download"
|
||||
)
|
||||
|
||||
# Unique constraint to prevent duplicate pending queue items per episode
|
||||
# An episode can only have one PENDING entry at a time
|
||||
# The status column allows failed items to remain in DB while new
|
||||
# pending items can be added (application-level dedup still required)
|
||||
__table_args__ = (
|
||||
Index(
|
||||
"ix_download_queue_episode_pending",
|
||||
"ix_download_queue_episode_status",
|
||||
"episode_id",
|
||||
"status",
|
||||
unique=True,
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user