Repository navigation
fix(email): stop blocking inline email sends on an analytics flush - #124631
Conversation
HTTP email sends captured their events through ph_scoped_capture, which builds a client per send and waits for it to upload before returning. Requests that send an email inline, such as signup and login codes, waited on that upload. Capture through the global posthoganalytics client again, which already sets the region super property and uploads in the background. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 43b649a0-cb22-4866-8c03-fb38148fd5ac
|
😎 Merged successfully - details. |
|
Risk: No findings This change routes inline (web-request) email analytics through the global posthoganalytics client instead of the per-send flushing client, so signup/login responses no longer wait on a cross-region analytics upload; Celery worker sends keep the dedicated flushing client. Both transports keep the cloud-only guard and the region super property, so I found no security regression — only the acknowledged, documented risk that an event enqueued just before a process exit can be lost. Sentinel reviewed |
🤖 CI report
|
| File | Comment lines | Added lines |
|---|---|---|
posthog/email.py |
2 | 5 |
This check does not block merging. It updates on every push and clears when the share drops.
There was a problem hiding this comment.
PostHog Review · Standard · reviewed bba4c6b: 2 Should fix.
This Standard review started from the posthog-review label. Comment @posthog review --deep for a Deep review, or @posthog help to see all commands.
See this review and its findings in PostHog Review.
yasen-posthog
left a comment
There was a problem hiding this comment.
Approved to unblock, just make sure to address the bot comments, and thank you 🙏
…uard A send that a Celery worker runs uses ph_scoped_capture again, so a recycled worker child does not drop the email events. Only sends outside a worker task, such as eager sends inside a request, use the global client. Both paths go through ScopedCapture, so a self-hosted instance does not send recipient addresses to the PostHog analytics project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Generated-By: PostHog Desktop Task-Id: 43b649a0-cb22-4866-8c03-fb38148fd5ac
Generated-By: PostHog Desktop Task-Id: 43b649a0-cb22-4866-8c03-fb38148fd5ac
Problem
ph_scoped_capture, which builds a new client per send and calls a blockingshutdown().Changes
posthoganalyticsclient. That client uploads in the background and already sets theregionsuper property.ph_scoped_capture, so a recycled worker child still flushes its events.is_cloud()guard, so a self-hosted instance sends no recipient addresses to the PostHog analytics project.How did you test this code?
Test rationale:
test_send_via_http_flushes_events_only_in_a_workercovers which client a send uses. It fails if a request send blocks on the scoped flush, if a worker send skips it, or if a self-hosted send captures events. The existingposthog/test/test_email.pycases still assert every captured event and its properties.hogli test posthog/test/test_email.pylocally.Release status
Docs update
None.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: PostHog Desktop (Claude Code), Opus 5.5 (
claude-opus-5-5)/writing-tests,/writing-pr-descriptions.Created with PostHog Desktop
🤖 Generated with Claude Code