Cache not expiring when model has empty update in transaction
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 35/100
Línea de trabajo
Comienza en el método _run_commit_callbacks de IdentityCache y sigue cómo se establece @transaction_changed_attributes y cómo ActiveRecord y ar_transaction_changes invocan after_commit para varias actualizaciones. Reproduce los tres ejemplos de transacciones y, después, verifica que la caché refleje el estado final confirmado del modelo sin provocar regresiones en la expiración normal de la caché.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
We've encountered a situation where the cache isn't expired if, within a transaction, a model has a "non-update" followed by an update. Here's the code that created a stale cache in our application:
def update_user(id, attributes) # hash
ApplicationRecord.transaction do
User.find(id).update(attributes.except(:email))
update_sign_in_information(id, attributes[:email])
end
end
def update_sign_in_information(user_id, email)
user = User.find(user_id)
user.update(email: email)
# other stuff
end
If only the email attribute is passed in, this leads to a stale cache. Here are some more examples that demonstrate the bug:
class Tester
def self.test
reset
ApplicationRecord.transaction do
user = User.first
user.update({})
user.update(name: "test2")
end
puts "###### user name: #{User.fetch(User.first.id).name}" # test2, good
reset
ApplicationRecord.transaction do
User.first.update({})
User.first.update(name: "test2")
end
puts "###### user name: #{User.fetch(User.first.id).name}" # test1, stale
reset
ApplicationRecord.transaction do
User.first.update(name: "test1")
User.first.update(name: "test2")
end
puts "###### user name: #{User.fetch(User.first.id).name}" # test1, stale
end
def self.reset
User.first.update(name: "test1")
User.fetch(User.first.id) # fill the cache
end
end
A similar "bug" exists in ActiveRecord:
class User < ApplicationRecord
after_commit :print_name
def print_name
puts user.name
end
end
ApplicationRecord.transaction do
User.first.update(name: "test1")
User.first.update(name: "test2")
end
# prints test1 after the whole transaction is committed
The bug goes pretty deep and seems to involve the activerecord and ar_transaction_changes gems. Essentially, the @transaction_changed_attributes variable that IdentityCache's _run_commit_callbacks method is checking is attached to the record, but the after_commit callback is only being called on the first instance even if the transaction contains multiple updates. Here's the monkey patch my team is currently considering adding to address the issue, but could lead to performance regressions:
def _run_commit_callbacks
# if destroyed? || transaction_changed_attributes.present?
expire_cache
# end
super
end
- Lenguaje dominante
- Ruby
- Estrellas
- 2k
- Forks
- 175
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la 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 Shopify/identity_cache
-
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
Shopify/identity_cache#568 · 1 comentario ·
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
Shopify/identity_cache#539 ·
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
Shopify/identity_cache#535 · 1 comentario ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 42/100
Shopify/identity_cache#533 · 1 comentario ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 25/100
Shopify/identity_cache#525 · 4 comentarios ·
Todos los issues de Shopify/identity_cache
Issues similares
-
[bug]: Sticky Streak DisappearedAbiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
Použiť Redis pre ActionCableAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
slovensko-digital/autogram-portal#392 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
voxpupuli/puppet-quadlets#122 · 5 comentarios ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
TheOdinProject/curriculum#31452 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100