-
Notifications
You must be signed in to change notification settings - Fork 21.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't clear digest cache in test environment #27271
Conversation
Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @schneems (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. This repository is being automatically checked for code quality issues using Code Climate. You can see results for this analysis in the PR status below. Newly introduced issues should be fixed before a Pull Request is considered ready to review. Please see the contribution instructions for more information. |
@matthewd it would be great to have this one in 5.0.1. |
Why it degradates performance? I prefer to fix the performance issue before disabling it. |
Because it recompiles templates on every request, instead of using cached ones. |
To be clear, you're not saying that something got slower... you're saying that the change in #20384 can be adjusted to cache more aggressively in tests, and that makes them faster. Right? |
Nope. The change in #20384 totally disables caching templates between requests. I've been migrating from 4.2 and found that integration tests got almost 2 times slower. With stackprof I've found that there got too much time in |
I've added this lines to test helper, and this decreased tests time back to 4.2's time: class << ActionView::LookupContext::DetailsKey
def clear
end
end |
Indeed, I think it's not good idea to clear digest cache if |
@@ -39,7 +39,7 @@ class Railtie < Rails::Engine # :nodoc: | |||
|
|||
initializer "action_view.per_request_digest_cache" do |app| | |||
ActiveSupport.on_load(:action_view) do | |||
if app.config.consider_all_requests_local | |||
if app.config.consider_all_requests_local && !Rails.env.test? | |||
app.executor.to_run ActionView::Digestor::PerExecutionDigestCacheExpiry |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like we could get rid of the if
entirely, and change this to use app.reloader.to_run
instead of the executor.
Then it'll automatically get run as part of the reloading in development (if reloading is enabled), and be skipped in test and production (unless reloading is enabled). If it works, that feels like a better statement of our intent -- this current consider_all_requests_local
check feels more like an indirect attempt to avoid running in production.
Are you up for trying that instead?
(FYI, this won't make 5.0.1 -- as we're in RC stage, the only things that will be added are fixes for regressions relative to 5.0.0. But it does seem a reasonable candidate for backporting for the future 5.0.2.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I'll try it tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify. Does reloader run when templates changed, or it tracks only .rb files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, good point. I thought it did, but it looks like I was wrong.
So looking at how views actually get handled... it seems cache_template_loading
is what should be deciding whether the digest cache should persist (true), or get cleared for each execution (false).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you think it's overkill? I mean, the only place where it's used is dev env. I can't think any other scenario up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point of the config settings is to abstract away the environment definitions. People can define their own environments, for example.
Unless I'm confused, I'm just suggesting we change the if
to use ! cache_template_loading
where it currently uses consider_all_requests_local
, so I'm not sure where the overkill is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It uses existing config option, but we would define one more. Not really a problem for me.
What if we use clear_compiled_templates instead? The idea is to make it safe for production by default, and not to treat missing value (nil) as true. It would require to enable it explicitly in development.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or recompile_templates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cache_template_loading
is an already-existing config setting
07c0912
to
9f31baa
Compare
@@ -39,7 +39,7 @@ class Railtie < Rails::Engine # :nodoc: | |||
|
|||
initializer "action_view.per_request_digest_cache" do |app| | |||
ActiveSupport.on_load(:action_view) do | |||
if app.config.consider_all_requests_local | |||
if ActionView::Resolver.caching? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use this instead of cache_template_loading
, because this one is set to default value if not configured on line 35.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this doing what we want? I think it needs to be unless
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, ActionView::Resolver.caching?
is on in production by default (because of the cache_classes
fallback above).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch! 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Waiting for github getting up to repush.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pushed
Not sure. It just fixes this leak when |
It disables recompilation of templates on every request in test env.
1031d6a
to
2380354
Compare
@printercu I don't have experience in this area of the code, but this looks sweet!!! |
TL/DR
rspec spec/integration
. Before: 35sec. After patch: 20sec.#20384 implemented template digest expiry for dev requests. It's enabled by default for test env, which is not required and degradates test performance.
I'm not sure if there should be testcase for this commit.
UPD There is failing test on travis. But it's for actioncable, and passes locally for me.