Twilio send blocks the event loop — offload to a thread #56
Labels
No labels
area:ai
area:ci-cd
area:notifications
area:observability
area:public-pages
backlog
bug
duplicate
enhancement
help wanted
invalid
question
type:decision
type:feature
type:infra
type:maintenance
type:security
v1.0.1
v1.1.0
v1.2.0
v1.3.0
v2.0.0
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/WeatherBot#56
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
_send_twilio_sms(app/services/notifiers/sms.py:111-124) calls thesynchronous Twilio SDK on the shared event loop (FastAPI + APScheduler +
Discord + Matrix per the lifespan). Wrap in
await asyncio.to_thread(...)(or switch to an httpx call). Grep for othersynchronous SDK calls while there (
TimezoneFinder()init inresolve_location_nws, scheduler.py:141-143, is also heavyweight on-loop —instantiate once at module level or offload).
Acceptance criteria:
Filed from the 2026-07-17 codebase audit (
docs/.internal/report-2026-07-17.md), finding F-17.Done in #99 (merged).
_send_twilio_smsnow wraps the synchronous Twilio SDKmessages.create(...)inawait asyncio.to_thread(...), so a slow Twilio call no longer blocks the shared event loop. The voip.ms httpx path was already async and is unchanged.Follow-up: the second acceptance item (TimezoneFinder constructed once / off-loop, in
scheduler.py:resolve_location_nws) was out of scope for the notifier-only Phase A change and is being completed in the Phase B pipeline PR (with #53, which also touchesscheduler.py). The Twilio event-loop fix landed here in #99.Second acceptance item completed in #100 (merged):
TimezoneFinderis now a module-level lazy singleton inscheduler.pyinstead of being constructed on everyresolve_location_nwscall. Both acceptance items (Twilio off-loop in #99, TimezoneFinder in #100) are now done.