From 16afc56c0a7f5f1f618d169e9cd8fd5317fa8c3d Mon Sep 17 00:00:00 2001 From: "n.siegfried" Date: Thu, 20 Aug 2026 18:05:43 -0700 Subject: [PATCH] CR-011 transport - pin the EHLO name; DNS trouble was stalling every send 5s smtplib calls getfqdn() on every connect when local_hostname is not given, and that reverse-DNS lookup blocks ~5s per send whenever DNS is slow or down (found when the office link dropped today: qa_gate_check's sink saw one mail per ~5s and its 12s waits timed out). Sends are sequential background tasks, so the stall compounded across a notification batch - in production a QA transition with a 3-person group would take 15+ seconds to finish mailing. socket.gethostname() never touches the network; the EHLO name is now computed once. Measured against the capture sink: 5.3s -> 0.3s for a two-recipient batch. Server mail path otherwise untouched. Item: CR-011 (the send path's transport). Co-Authored-By: Claude Fable 5 --- server/notify.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server/notify.py b/server/notify.py index d28edc0..f2cf8d6 100644 --- a/server/notify.py +++ b/server/notify.py @@ -12,6 +12,7 @@ number and a deep link, not the work-package contents. """ import os import smtplib +import socket import uuid import logging from email.message import EmailMessage @@ -107,7 +108,13 @@ def send_email(s: dict, to_addr: str, subject: str, body: str) -> None: port = int(s.get("smtp_port") or 587) user = s.get("smtp_username") or "" pw = os.getenv("SMTP_PASSWORD", "") - with smtplib.SMTP(host, port, timeout=15) as srv: + # local_hostname pins the EHLO name. Without it smtplib calls getfqdn() on + # EVERY connect, and that reverse-DNS lookup stalls ~5s per send whenever DNS + # is slow or unreachable - sends are sequential background tasks, so a batch + # of notifications trickled out one per five seconds. gethostname() never + # touches the network. Found 2026-08-20 when the office link dropped. + with smtplib.SMTP(host, port, timeout=15, + local_hostname=(socket.gethostname() or "wp-suite")) as srv: if s.get("smtp_use_tls", True): srv.starttls() if user: