This commit is contained in:
2026-03-18 17:30:13 +01:00
parent 58a233236c
commit d80d912fb3
36 changed files with 3502 additions and 4 deletions
+1
View File
@@ -0,0 +1 @@
# Definizioni job arq
+77
View File
@@ -0,0 +1,77 @@
"""
Job arq: sync_mailbox trigger manuale per forzare la sincronizzazione di una casella.
Questo job viene usato per:
- Forzare una sync immediata dopo la creazione di una nuova casella
- Resync manuale da parte dell'admin
- Retry dopo un errore (called dal pool monitor)
Non sostituisce il loop IMAP continuo (IMAPConnection); è un one-shot job.
"""
import logging
from typing import Any
from app.database import AsyncSessionLocal
from app.imap.reconnect import ExponentialBackoff
from app.imap.sync import sync_new_messages
from app.models import Mailbox
logger = logging.getLogger(__name__)
async def sync_mailbox(ctx: dict[str, Any], mailbox_id: str) -> dict:
"""
Job arq: sincronizza una singola casella PEC.
Args:
ctx: contesto arq (contiene redis, pool reference)
mailbox_id: UUID della casella da sincronizzare
Returns:
dict con risultato del job
"""
redis_client = ctx.get("redis")
async with AsyncSessionLocal() as db:
mailbox = await db.get(Mailbox, mailbox_id)
if not mailbox:
return {"status": "error", "message": f"Mailbox {mailbox_id} non trovata"}
if mailbox.status not in ("active", "error"):
return {
"status": "skipped",
"message": f"Mailbox status={mailbox.status}, skip",
}
from app.imap.connection import IMAPConnection
creds = IMAPConnection._decrypt_creds(mailbox)
try:
from app.imap.connection import IMAPConnection
conn = IMAPConnection(mailbox_id=mailbox_id, redis_client=redis_client)
client = await conn._connect(creds)
n = await sync_new_messages(client, mailbox, db, redis_client)
try:
await client.logout()
except Exception:
pass
return {
"status": "ok",
"mailbox": mailbox.email_address,
"new_messages": n,
}
except Exception as e:
logger.error(f"[sync_mailbox] {mailbox_id} errore: {e}", exc_info=True)
return {
"status": "error",
"mailbox": mailbox.email_address,
"message": str(e),
}