Fix routing rule
This commit is contained in:
@@ -8,8 +8,8 @@ Flusso completo:
|
||||
- legge le NotificationRule attive del tenant con event_type="new_message"
|
||||
- applica i filtri opzionali (mailbox_id, direction, pec_type)
|
||||
- per ogni regola che matcha: crea NotificationLog(status=pending)
|
||||
- enqueue del job arq dispatch_notification con defer 5s
|
||||
(per dare tempo al DB di committare prima che il job legga)
|
||||
- restituisce lista di log_id: il chiamante accoda i job DOPO db.commit()
|
||||
(evita race condition: il job apre una nuova sessione DB)
|
||||
4. dispatch_notification(ctx, notification_log_id):
|
||||
- legge NotificationLog + NotificationChannel dal DB
|
||||
- controlla circuit breaker
|
||||
@@ -234,38 +234,49 @@ async def evaluate_and_enqueue_notifications(
|
||||
message: Message,
|
||||
mailbox: Mailbox,
|
||||
db: Any, # AsyncSession – evito import circolare
|
||||
redis_client: Any, # ArqRedis
|
||||
) -> None:
|
||||
) -> list[str]:
|
||||
"""
|
||||
Valuta le regole di notifica per un messaggio appena salvato e accoda i job.
|
||||
Valuta le regole di notifica per un messaggio appena salvato,
|
||||
crea i NotificationLog e restituisce i loro ID.
|
||||
|
||||
NON accoda i job arq: il chiamante deve farlo DOPO db.commit()
|
||||
per evitare race condition (il job dispatch_notification apre una nuova
|
||||
sessione DB e deve trovare il NotificationLog gia' committato).
|
||||
|
||||
Chiamata da sync.py dopo _save_message e index_message.
|
||||
Non solleva eccezioni: gli errori vengono loggati ma non propagati per
|
||||
non interrompere il flusso di sincronizzazione IMAP.
|
||||
|
||||
Args:
|
||||
message: messaggio appena salvato nel DB (flush, non commit)
|
||||
mailbox: casella di appartenenza
|
||||
db: sessione DB (open, con flush del messaggio)
|
||||
redis_client: ArqRedis per enqueue_job
|
||||
message: messaggio appena salvato nel DB (flush, non commit)
|
||||
mailbox: casella di appartenenza
|
||||
db: sessione DB (open, con flush del messaggio)
|
||||
|
||||
Returns:
|
||||
Lista di notification_log_id (str) da accodare dopo il commit.
|
||||
"""
|
||||
try:
|
||||
await _do_evaluate_and_enqueue(message, mailbox, db, redis_client)
|
||||
return await _do_evaluate_and_enqueue(message, mailbox, db)
|
||||
except Exception as exc:
|
||||
logger.error(
|
||||
f"Errore evaluate_and_enqueue_notifications per messaggio "
|
||||
f"{message.id}: {exc}",
|
||||
exc_info=True,
|
||||
)
|
||||
return []
|
||||
|
||||
|
||||
async def _do_evaluate_and_enqueue(
|
||||
message: Message,
|
||||
mailbox: Mailbox,
|
||||
db: Any,
|
||||
redis_client: Any,
|
||||
) -> None:
|
||||
"""Logica interna – puo' sollevare eccezioni."""
|
||||
) -> list[str]:
|
||||
"""
|
||||
Logica interna – puo' sollevare eccezioni.
|
||||
|
||||
Crea i NotificationLog e restituisce i loro ID.
|
||||
NON accoda job arq: il chiamante lo fa dopo db.commit().
|
||||
"""
|
||||
|
||||
# Carica regole attive per questo tenant con event_type = "new_message"
|
||||
rules_result = await db.execute(
|
||||
@@ -280,9 +291,9 @@ async def _do_evaluate_and_enqueue(
|
||||
rules: list[NotificationRule] = list(rules_result.scalars().all())
|
||||
|
||||
if not rules:
|
||||
return
|
||||
return []
|
||||
|
||||
enqueued_count = 0
|
||||
log_ids: list[str] = []
|
||||
|
||||
for rule in rules:
|
||||
channel = rule.channel
|
||||
@@ -336,31 +347,22 @@ async def _do_evaluate_and_enqueue(
|
||||
db.add(log)
|
||||
await db.flush() # ottieni log.id
|
||||
|
||||
# Enqueue arq job con defer 5s per attendere il commit DB
|
||||
try:
|
||||
await redis_client.enqueue_job(
|
||||
"dispatch_notification",
|
||||
str(log.id),
|
||||
_defer_by=timedelta(seconds=5),
|
||||
)
|
||||
enqueued_count += 1
|
||||
logger.info(
|
||||
f"[notify] Enqueued dispatch_notification per regola "
|
||||
f"{rule.name!r} -> canale {channel.name!r} "
|
||||
f"(log_id={log.id})"
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
f"[notify] Impossibile enqueue dispatch_notification "
|
||||
f"per log {log.id}: {e}"
|
||||
)
|
||||
# Raccoglie log_id: il job viene accodato dal chiamante DOPO db.commit()
|
||||
log_ids.append(str(log.id))
|
||||
logger.info(
|
||||
f"[notify] NotificationLog creato per regola "
|
||||
f"{rule.name!r} -> canale {channel.name!r} "
|
||||
f"(log_id={log.id})"
|
||||
)
|
||||
|
||||
if enqueued_count > 0:
|
||||
if log_ids:
|
||||
logger.info(
|
||||
f"[notify] Messaggio {message.id}: "
|
||||
f"{enqueued_count} notifiche accodate"
|
||||
f"{len(log_ids)} notifiche pronte per dispatch"
|
||||
)
|
||||
|
||||
return log_ids
|
||||
|
||||
|
||||
# ─── Job arq principale ───────────────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user