feat(downloads): M3 — per-user quota + retention GC
- downloads/quota.py: per-user limits (DownloadQuota row or sysconfig defaults; unlimited bypass), footprint = distinct ready-asset bytes the user holds, check_enqueue (max_jobs + max_bytes hard at enqueue), at_concurrency_limit (worker-side max_concurrent), usage snapshot - downloads/gc.py: run_download_gc — pre-expiry warning (once, gc_notified flag), TTL deletion (files + row; FK SET NULL orphans holders' jobs -> 'expired'), LRU eviction over a total-cache cap; notifies holders on each event - migration 0038: media_assets.gc_notified - config/sysconfig: download_total_max_bytes (0=unlimited) in the downloads group - service.enqueue enforces quota; worker claim skips users at their concurrency limit - scheduler: download_gc job registered (default 360 min, admin-tunable) Verified on localdev: footprint accounting, max_jobs block, pre-expiry warning (notifies all holders), TTL deletion (asset+files gone, dirs pruned, jobs orphaned, holders notified).
This commit is contained in:
parent
7f9847c2c2
commit
7148335c09
9 changed files with 325 additions and 15 deletions
|
|
@ -12,7 +12,7 @@ from sqlalchemy import func, select
|
|||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.downloads import formats
|
||||
from app.downloads import formats, quota
|
||||
from app.models import DownloadJob, MediaAsset
|
||||
|
||||
|
||||
|
|
@ -67,7 +67,10 @@ def enqueue(
|
|||
profile_id: int | None = None,
|
||||
display_name: str | None = None,
|
||||
) -> DownloadJob:
|
||||
"""Queue a download for `user_id`. Returns the DownloadJob (already `done` on a cache hit)."""
|
||||
"""Queue a download for `user_id`. Returns the DownloadJob (already `done` on a cache hit).
|
||||
|
||||
Raises quota.QuotaExceeded if the user is at their job-count or footprint cap."""
|
||||
quota.check_enqueue(db, user_id)
|
||||
spec = formats.normalize(spec)
|
||||
sig = formats.format_sig(spec)
|
||||
asset = get_or_create_asset(db, source_kind, source_ref, sig)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue