Remove legacy synchroneus import

This commit is contained in:
2026-05-16 13:33:53 -03:00
parent 026efec79b
commit b70ac9bc6f
5 changed files with 51 additions and 45 deletions
+26 -1
View File
@@ -1,18 +1,25 @@
from __future__ import annotations
import fcntl
from pathlib import Path
import threading
from dataclasses import dataclass
from typing import IO
@dataclass
class InboxRunLease:
inbox_id: str
_locks: list[threading.Lock]
_lock_file: IO[str] | None = None
_released: bool = False
def release(self) -> None:
if not self._released:
self._released = True
if self._lock_file:
fcntl.flock(self._lock_file.fileno(), fcntl.LOCK_UN)
self._lock_file.close()
for lock in reversed(self._locks):
lock.release()
@@ -28,16 +35,34 @@ class InboxRunLocks:
self._guard = threading.Lock()
self._global_lock = threading.Lock()
self._locks: dict[str, threading.Lock] = {}
self._lock_path = Path("data/import.lock")
def _acquire_file_lock(self, *, blocking: bool) -> IO[str] | None:
self._lock_path.parent.mkdir(parents=True, exist_ok=True)
handle = self._lock_path.open("a+", encoding="utf-8")
flags = fcntl.LOCK_EX if blocking else fcntl.LOCK_EX | fcntl.LOCK_NB
try:
fcntl.flock(handle.fileno(), flags)
return handle
except BlockingIOError:
handle.close()
return None
def acquire(self, inbox_id: str, *, blocking: bool = False) -> InboxRunLease | None:
if not self._global_lock.acquire(blocking=blocking):
return None
lock_file = self._acquire_file_lock(blocking=blocking)
if not lock_file:
self._global_lock.release()
return None
with self._guard:
lock = self._locks.setdefault(inbox_id, threading.Lock())
if not lock.acquire(blocking=blocking):
fcntl.flock(lock_file.fileno(), fcntl.LOCK_UN)
lock_file.close()
self._global_lock.release()
return None
return InboxRunLease(inbox_id=inbox_id, _locks=[self._global_lock, lock])
return InboxRunLease(inbox_id=inbox_id, _locks=[self._global_lock, lock], _lock_file=lock_file)
def active(self, inbox_id: str) -> bool:
lease = self.acquire(inbox_id, blocking=False)
-39
View File
@@ -916,42 +916,3 @@ def api_import_job(job_id: str):
def api_inbox_status(inbox_id: str, session: Session = Depends(get_db)):
return _inbox_status_payload(inbox_id, session)
@app.post("/api/admin/process-now", dependencies=dashboard_post_auth)
def api_process_now(body: ProcessNowRequest, session: Session = Depends(get_db)):
try:
inbox = settings.get_inbox(body.inbox_id)
except KeyError:
raise HTTPException(status_code=404, detail=f"Unknown inbox: {body.inbox_id}") from None
lease = inbox_run_locks.acquire(inbox.id, blocking=False)
if not lease:
raise HTTPException(status_code=409, detail=f"Inbox {inbox.id} is already processing.")
with lease:
summary = process_inbox(session, settings, inbox, mode=body.mode, limit=body.limit)
return summary.__dict__
@app.post("/api/admin/backlog", dependencies=dashboard_post_auth)
def api_backlog(body: BacklogRequest, session: Session = Depends(get_db)):
try:
inbox = settings.get_inbox(body.inbox_id)
except KeyError:
raise HTTPException(status_code=404, detail=f"Unknown inbox: {body.inbox_id}") from None
lease = inbox_run_locks.acquire(inbox.id, blocking=False)
if not lease:
raise HTTPException(status_code=409, detail=f"Inbox {inbox.id} is already processing.")
with lease:
summary = process_inbox(
session,
settings,
inbox,
folder=body.folder or inbox.folder,
mode="backlog",
since=body.since,
before=body.before,
limit=body.limit,
dry_run=body.dry_run,
reprocess=body.reprocess,
mark_seen=body.mark_seen,
)
return summary.__dict__