ActiveRecord::ConnectionFailed not caught by the failsafe (terminated connection surfaces as an error)
@ajaynomics ya está trabajando en esto.
Desde el 24/6/2026.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 76/100
Línea de trabajo
Comienza en SolidCache::Store::Failsafe::TRANSIENT_ACTIVE_RECORD_ERRORS y revisa las pruebas existentes de failsafe, si las hay. Reproduce el escenario de una conexión de PostgreSQL terminada o añade una prueba de regresión específica. Después, verifica que ActiveRecord::ConnectionFailed se trate como un fallo transitorio y que la caché se degrade a un miss en lugar de propagar el error.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Ruby
- Estrellas
- 1k
- Forks
- 82
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Sin plantilla de pull request
- Sin guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de rails/solid_cache
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
rails/solid_cache#244 · 3 comentarios ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 45/100
rails/solid_cache#195 · 6 comentarios ·
-
UNLOGGED TABLE's in postgresql.Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
rails/solid_cache#101 · 5 comentarios · 11 reacciones ·
Todos los issues de rails/solid_cache
Issues similares
-
Add Nagoya Ruby Kaigi 05Abiertocontent good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 66/100
rubyevents/rubyevents#2182 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Homebrew/homebrew-cask#293134 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
notch8/iiif_print#430 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
Los mantenedores suelen responder en 1 día