Backend IMAP calls block the event loop and have no timeout #5

Closed
opened 2026-06-17 17:12:30 +01:00 by lyrathorpe · 0 comments
Owner

handle_stat (proxy_server.py:233) and handle_list (proxy_server.py:244) call IMAPBackend.fetch_message_size synchronously inside a loop, on the asyncio event loop thread. Every blocking imaplib round-trip stalls all other clients. There is also no socket timeout on imaplib (smtplib already uses timeout=30), so a dead backend hangs the session indefinitely.

Fix:

  • Either fetch all sizes in a single round-trip (UID FETCH 1:* (RFC822.SIZE)) or wrap the blocking calls in asyncio.to_thread.
  • Apply a connection/socket timeout to the IMAP client.

Acceptance:

  • STAT/LIST do not block the event loop.
  • An unresponsive IMAP backend fails within a bounded time rather than hanging.
handle_stat (proxy_server.py:233) and handle_list (proxy_server.py:244) call IMAPBackend.fetch_message_size synchronously inside a loop, on the asyncio event loop thread. Every blocking imaplib round-trip stalls all other clients. There is also no socket timeout on imaplib (smtplib already uses timeout=30), so a dead backend hangs the session indefinitely. Fix: - Either fetch all sizes in a single round-trip (UID FETCH 1:* (RFC822.SIZE)) or wrap the blocking calls in asyncio.to_thread. - Apply a connection/socket timeout to the IMAP client. Acceptance: - STAT/LIST do not block the event loop. - An unresponsive IMAP backend fails within a bounded time rather than hanging.
lyrathorpe added the enhancement label 2026-06-17 17:12:30 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: lyrathorpe/legacy-email-proxy#5