diff --git a/worker/src/main.py b/worker/src/main.py index bf79dd5..ff4590f 100644 --- a/worker/src/main.py +++ b/worker/src/main.py @@ -59,20 +59,33 @@ async def process_notification_queue(pool: asyncpg.Pool, bot: ExtBot) -> int: """Process pending notifications from the retry queue.""" rows = await pool.fetch(""" SELECT id, ad_id, telegram_id, message_text, type, attempts, - max_attempts, last_error, updated_at + max_attempts, last_error, updated_at, created_at FROM notification_queue WHERE status IN ('pending', 'failed') - ORDER BY attempts ASC, updated_at ASC - LIMIT 50 + ORDER BY attempts ASC, created_at ASC + LIMIT 200 """) + # Log queue depth + queue_stats = await pool.fetchrow("SELECT count(*) FROM notification_queue WHERE status IN ('pending', 'failed')") + total_queued = queue_stats["count"] + logger.info("Notification queue: %d total, processing up to %d", total_queued, len(rows)) + processed = 0 for row in rows: - backoff_min = min(2 ** row["attempts"], 60) - retry_after = row["updated_at"] + timedelta(minutes=backoff_min) + # Pending (never tried) — send immediately + if row["status"] == "pending": + backoff_min = 0 + else: + # Failed — exponential backoff from created_at (fixed timeline) + backoff_min = min(2 ** row["attempts"], 60) + + retry_after = row["created_at"] + timedelta(minutes=backoff_min) if datetime.now(tz=timezone.utc) < retry_after: + logger.debug("Skipping notification %s — retry after %s (now %s)", + row["id"], retry_after, datetime.now(tz=timezone.utc)) continue try: