Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

ActiveRecord::ConnectionFailed not caught by the failsafe (terminated connection surfaces as an error)

Open Beginner friendly
#307 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
postgresql, rails, ruby
Domain
backend, databases

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from rails/solid_cache

All issues in rails/solid_cache

Similar issues

More Ruby issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.