ActiveRecord::ConnectionFailed not caught by the failsafe (terminated connection surfaces as an error)
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 76/100
Research direction
Start at SolidCache::Store::Failsafe::TRANSIENT_ACTIVE_RECORD_ERRORS and review the existing failsafe tests, if present. Reproduce the terminated PostgreSQL connection scenario or add a focused regression test, then verify that ActiveRecord::ConnectionFailed is treated as a transient failure and the cache degrades to a miss instead of propagating the error.
Written by the indexing model from the issue text.
Description
Summary
SolidCache::Store::Failsafe::TRANSIENT_ACTIVE_RECORD_ERRORS rescues ActiveRecord::ConnectionNotEstablished but not ActiveRecord::ConnectionFailed. When the cache database connection is terminated mid-transaction, Solid Cache raises ConnectionFailed instead of degrading to a cache miss, so the error propagates to the caller (a 500 on a web request, for example).
How we hit it
We run Solid Cache on a dedicated PostgreSQL database and set idle_in_transaction_session_timeout on that connection to bound row-lock contention on solid_cache_entries. A hot key_hash gets held by Entry.lock_and_write while the Ruby block runs, and under load the holding thread can stay idle-in-transaction long enough for PostgreSQL to terminate the backend:
PG::ConnectionBad: PQconsumeInput() FATAL: terminating connection due to idle-in-transaction timeout
The write that follows the SELECT ... FOR UPDATE inside lock_and_write then raises ActiveRecord::ConnectionFailed. That class is a subclass of ActiveRecord::StatementInvalid (added in Rails 7.1), not of ActiveRecord::ConnectionNotEstablished, so the current failsafe list does not catch it.
Reproduction
conn = SolidCache::Record.connection
conn.execute("SET idle_in_transaction_session_timeout = '300ms'")
SolidCache::Entry.lock_and_write("probe") do |_value|
sleep 1 # transaction stays idle > 300ms -> PostgreSQL kills the session
"v"
end
# => ActiveRecord::ConnectionFailed: ... terminating connection due to idle-in-transaction timeout
SolidCache::Store::Failsafe::TRANSIENT_ACTIVE_RECORD_ERRORS.any? { |k| error.is_a?(k) }
# => false
Proposal
Add ActiveRecord::ConnectionFailed to TRANSIENT_ACTIVE_RECORD_ERRORS. A terminated connection is the kind of transient failure the cache should degrade on, consistent with the existing ConnectionNotEstablished entry.
TRANSIENT_ACTIVE_RECORD_ERRORS = [
ActiveRecord::AdapterTimeout,
ActiveRecord::ConnectionFailed, # added
ActiveRecord::ConnectionNotEstablished,
ActiveRecord::Deadlocked,
ActiveRecord::LockWaitTimeout,
ActiveRecord::QueryCanceled,
ActiveRecord::StatementTimeout
]
ActiveRecord::ConnectionFailed exists in Rails 7.1+, which is within Solid Cache's supported range, so referencing it directly is safe.
Happy to send a PR with a test if this looks right.
Environment: solid_cache 1.0.10, Rails 8.1, PostgreSQL 17.
- Dominant language
- Ruby
- Stars
- 1k
- Forks
- 82
- PR merge metrics
- No merged PRs in 30d
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- No contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rails/solid_cache
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
rails/solid_cache#244 · 3 comments ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 45/100
rails/solid_cache#195 · 6 comments ·
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
rails/solid_cache#101 · 5 comments · 11 reactions ·
All issues in rails/solid_cache
Similar issues
-
security
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
CircuitVerse/CircuitVerse#7967 · 1 comment · 1 reaction ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
simp/pupmod-simp-stunnel#173 ·
-
Polish QDrantOpen
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
o19s/quepid#1825 · 1 comment ·
Maintainers usually reply within 1 day