fix(downloads): accept download_id in history delete/retry endpoints, add unique index

This commit is contained in:
Will Miao
2026-07-18 21:10:42 +08:00
parent dc715aa273
commit f0bf2728c9
3 changed files with 256 additions and 26 deletions

View File

@@ -74,6 +74,8 @@ class DownloadQueueService:
);
CREATE INDEX IF NOT EXISTS idx_dh_completed ON download_history(completed_at DESC);
CREATE INDEX IF NOT EXISTS idx_dh_status ON download_history(status);
CREATE UNIQUE INDEX IF NOT EXISTS idx_dh_download_id
ON download_history(download_id) WHERE download_id IS NOT NULL;
"""
@classmethod
@@ -390,7 +392,7 @@ class DownloadQueueService:
)
conn.execute(
"""
INSERT INTO download_history (
INSERT OR IGNORE INTO download_history (
download_id, model_id, model_version_id, model_name,
version_name, thumbnail_url, status, error, file_path,
bytes_downloaded, total_bytes, completed_at
@@ -547,17 +549,27 @@ class DownloadQueueService:
"offset": offset,
}
async def delete_history_item(self, id: int) -> bool:
"""Delete a single history entry by its *id*.
async def delete_history_item(
self, id: Optional[int] = None, download_id: Optional[str] = None
) -> bool:
"""Delete a single history entry by *download_id* (preferred) or *id*.
Returns ``True`` if a row was deleted.
"""
async with self._lock:
conn = self._get_conn()
cursor = conn.execute(
"DELETE FROM download_history WHERE id = ?",
(id,),
)
if download_id:
cursor = conn.execute(
"DELETE FROM download_history WHERE download_id = ?",
(download_id,),
)
elif id is not None:
cursor = conn.execute(
"DELETE FROM download_history WHERE id = ?",
(id,),
)
else:
return False
conn.commit()
return cursor.rowcount > 0
@@ -614,21 +626,34 @@ class DownloadQueueService:
# Retry
# ------------------------------------------------------------------
async def retry_from_history(self, item_id: int) -> Optional[dict[str, Any]]:
async def retry_from_history(
self,
item_id: Optional[int] = None,
download_id: Optional[str] = None,
) -> Optional[dict[str, Any]]:
"""Re-queue a failed or canceled download from history.
Looks up the history record by its primary key. If the status is
``failed`` or ``canceled`` a new queue entry is created with the
same model metadata and a fresh download id, and the original
history entry is **deleted** to prevent exponential growth when
the retried item is later canceled or fails again and re-retried.
Looks up the history record by *download_id* (preferred) or
*item_id*. If the status is ``failed`` or ``canceled`` a new
queue entry is created with the same model metadata and a fresh
download id, and the original history entry is **deleted** to
prevent exponential growth when the retried item is later
canceled or fails again and re-retried.
"""
async with self._lock:
conn = self._get_conn()
row = conn.execute(
"SELECT * FROM download_history WHERE id = ?",
(item_id,),
).fetchone()
if download_id:
row = conn.execute(
"SELECT * FROM download_history WHERE download_id = ?",
(download_id,),
).fetchone()
elif item_id is not None:
row = conn.execute(
"SELECT * FROM download_history WHERE id = ?",
(item_id,),
).fetchone()
else:
return None
if row is None:
return None
status = str(row["status"])
@@ -660,7 +685,7 @@ class DownloadQueueService:
)
conn.execute(
"DELETE FROM download_history WHERE id = ?",
(item_id,),
(row["id"],),
)
conn.commit()
queued = conn.execute(