Conversation
|
r? @eileencodes (@rails-bot has picked a reviewer for you, use r? to override) |
|
👍 for this feature. I accidentally created a similar PR. Just curious, but why define |
|
@gingerlime From what I understand - If people have overwritten If |
|
Thanks @lsylvester. I see it as an omission from the original feature, but maybe it was intended this way? I'm not sure. Besides that, this PR should hopefully resolve (what looks to me like) a performance regression bug that happens in some cases even if you don't switch cache_versioning on (and already with Rails 5.2). In any case, keen to see this merged one way or another :) |
|
@gingerlime I wasn't ware of that performance regression. That is clearly a bug, and while I don't think that we can enable full relation cache versioning without some time to update In my opinion - if an object response to Let me know if you want to have a go at that otherwise I will make a PR when I have time. |
|
Thanks @lsylvester. I didn't get any response regarding this, so it's good that I'm not the only one who thinks this is a bug :) I guess the simplest fix would be to implement EDIT: I guess this simplest fix would conflict with your PR however... So another option is to implement this check inside the |
* After introducing cache versioning, even with cache versioning off there's a performance regression when passing an Active Record relation to cache * This happens in ActiveSupport::Cache inside `normalize_version` * This method would check if the relation responds to cache_version and if not, would recrusively normalize it with `to_a` * This would lead to the relation being retrieved from database and enumerated, causing the performance regression * This fix simply adds `cache_version` returning `nil` to Active Record relations * This is a temporary stopgap, until relation cache versioning is implemented. See rails#34378
|
@rafaelfranca referencing my comment
Is there any timeline for moving this forward? Happy to help if I can. |
3f32b21 to
126fa44
Compare
126fa44 to
45e650f
Compare
|
Will this make it into Rails 6 ? |
|
Hey @lsylvester, sorry for never getting to review this! After a pretty huge refactoring in 10919bf I've just gone ahead and merged this in 1da9a7e. I opted not to add the Thanks for working on this, I'm looking forward to this in 6.0! ❤️ |
Signed-off-by: Kasper Timm Hansen <kaspth@gmail.com>
|
@kaspth Any chance of this being backported into v5.2.x? I would reason that collection caching being a fully working feature in v5.1 and regressing in v5.2 makes this a worthy candidate. |
|
It’s not broken in 5.2, collections just weren’t supported. They will be in 6.0. |
class FooController < ApplicationController
def bar
@xyz = Xyz.all
end
end<% cache(@xyz) do %>
<!-- -->
<% end %>
In 5.1.x the code as outlined above does cache collection and on non-initial hits only queries for Would you like me building a sample test case to demonstrate further? |
|
Gotcha, feel free to send a fix then, don’t think we want to back port since it’s a lot of code. |
|
@kaspth Just to be completely sure on the meaning of "fix" & spare wasted time - are you proposing I create a backport of this PR to |
|
@kaspth Kasper, I'm using When However, after this PR was merged in 1da9a7e,
|
|
Pinging @lsylvester as well |
|
Has anything happend with @feliperaul's comment above about relations not actually having a It also seems like this would not "just work" with |
|
If anyone else ends up here from a web search looking into why If you have an Rails version >= 6.0 and < 6.1, you can put this backport in an initializer: if Rails.version < "6.1.0"
class ActiveRecord::Relation
def cache_key_with_version
if version = cache_version
"#{cache_key}-#{version}"
else
cache_key
end
end
end
else
raise "ActiveRecord::Relation cache_key_with_version backport no longer required in Rails >= 6.1.0."
end |
Cache versioning enables the same cache key to be reused when the object being cached changes by moving the volatile part of the cache key out of the cache key and into a version that is embedded in the cache entry.
This is already occurring when the object being cached is an
ActiveRecord::Base, but when caching anActiveRecord::Relationwe are currently still putting the volatile information (max updated at and count) as part of the cache key.This PR moves the volatile part of the relations cache_key into the cache_version to support recycling cache keys for
ActiveRecord::Relations.