Cache not expiring when model has empty update in transaction
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 35/100
Hướng nghiên cứu
Bắt đầu từ phương thức _run_commit_callbacks của IdentityCache và theo dõi cách @transaction_changed_attributes được thiết lập cũng như cách ActiveRecord và ar_transaction_changes gọi after_commit cho nhiều lần cập nhật. Tái hiện ba ví dụ về transaction, sau đó xác minh rằng cache phản ánh trạng thái cuối cùng đã commit của model mà không gây hồi quy đối với việc hết hạn cache thông thường.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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
- Ngôn ngữ chính
- Ruby
- Star
- 2k
- Fork
- 175
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của Shopify/identity_cache
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
Shopify/identity_cache#568 · 1 bình luận ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
Shopify/identity_cache#539 ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
Shopify/identity_cache#535 · 1 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 42/100
Shopify/identity_cache#533 · 1 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
Shopify/identity_cache#525 · 4 bình luận ·
Tất cả issue của Shopify/identity_cache
Issue tương tự
-
Falha nos links do postĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
temporalio/sdk-ruby#625 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 94/100
zerocracy/judges-action#2803 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
empty tone.rbĐang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
-
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 92/100