fix(analytics): use std::thread for record_analytics_event to avoid postgres Drop abort#1477
Open
bingran-you wants to merge 1 commit intodevfrom
Open
fix(analytics): use std::thread for record_analytics_event to avoid postgres Drop abort#1477bingran-you wants to merge 1 commit intodevfrom
bingran-you wants to merge 1 commit intodevfrom
Conversation
…stgres Drop abort The `/analytics/track` handler was still wrapping `AccountStore::record_analytics_event` in `tokio::task::spawn_blocking`. The same pattern caused the production signup crash loop fixed in PR #1454 (see issue #1451): r2d2 pool recycling drops a sync `postgres::Client`, whose Drop impl runs `Runtime::block_on`; if the thread still carries a tokio runtime context, that panics with "Cannot start a runtime from within a runtime" and — because it happens in a destructor — aborts the whole worker instead of unwinding. Adds `account_store::run_blocking`, a `std::thread::spawn` + `oneshot` helper meant to be used wherever a closure may (directly or indirectly) drop a sync postgres client, and switches `/analytics/track` over to it. Follow-up callers in auth.rs / billing.rs can migrate incrementally. Refs #1476, #1451, #1454.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/analytics/trackstill wrappedAccountStore::record_analytics_eventintokio::task::spawn_blocking, the exact pattern that caused the production signup crash loop fixed in #1454 (root cause: #1451). r2d2 pool recycling drops a syncpostgres::Client; its Drop callsRuntime::block_on, which panics "Cannot start a runtime from within a runtime" when the thread still carries a tokio runtime context. Because it fires in a destructor, the panic aborts the worker instead of unwinding.account_store::run_blocking, astd::thread::spawn+tokio::sync::oneshothelper with the same ergonomics asspawn_blockingbut without the poisoned runtime context, and switches the/analytics/trackhandler over to it.service/auth.rs— 40+ sites;service/billing.rs— 5 sites) can migrate incrementally on top of this helper.Closes #1476. Related: #1451, #1454.
Why this matters
Production (dowhizprod1) and staging (dowhizstaging) had accumulated 110 / 139 PM2 restarts respectively before PR #1454 stabilized the signup path on 2026-04-20 21:06 UTC. Any user hitting
/analytics/trackunder load could still trigger the same abort on a recycled postgres connection. This closes that path.Test plan
cargo check -p scheduler_module --lib— clean, no new warnings.pm2 logs dw_workeron staging for absence of "Cannot start a runtime from within a runtime" panics during analytics traffic.task::spawn_blocking(move || store.X())callsites inauth.rs/billing.rstorun_blocking(follow-up PR).