dc94893dc5
| # | Issue | Location | |---|-------|----------| | 1 | **Archiver backs up deleted files** — `get_unbacked_files` never checks `is_deleted`, so files the scanner marked missing still get archived (wastes media, fails at tar assembly when source is gone) | `archiver.py:157-163` | | 2 | **Hashing phase marks wrong files as deleted** — after one sub-batch finishes, the code iterates over ALL fetched records (`path_to_record`) not just the completed sub-batch. Files in pending sub-batches get falsely `is_deleted=True` if not on disk | `scanner.py:854-861` | | 3 | **Multiple threads mutate ORM objects concurrently** — `ThreadPoolExecutor` workers share and write to session-bound objects (`sha256_hash`, `is_deleted`) from different threads. SQLAlchemy sessions are not thread-safe | `scanner.py:814-861` |
31 lines
670 B
Python
31 lines
670 B
Python
"""add_is_cancelled_to_jobs
|
|
|
|
Revision ID: 7f8e9d10c2a3
|
|
Revises: e851b23b0f5d
|
|
Create Date: 2026-04-30 15:00:00.000000
|
|
|
|
"""
|
|
|
|
from typing import Sequence, Union
|
|
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision: str = "7f8e9d10c2a3"
|
|
down_revision: Union[str, Sequence[str], None] = "e851b23b0f5d"
|
|
branch_labels: Union[str, Sequence[str], None] = None
|
|
depends_on: Union[str, Sequence[str], None] = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column(
|
|
"jobs",
|
|
sa.Column("is_cancelled", sa.Boolean(), nullable=False, server_default="0"),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column("jobs", "is_cancelled")
|