-
Notifications
You must be signed in to change notification settings - Fork 284
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
Fixes #37109 - allow to use eager loading on latest_version_object #10865
Conversation
Test failures look related. |
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.
Great find @sbernhard, thanks!
I tested this on my setup. With my ~20 CVs with 2 versions each, this improved my loading time from >3 sec every time to about 2.5 sec.
just a couple minor comments/questions
d8b9090
to
8a588c8
Compare
Katello tests are now green. |
@sbernhard looking good, please squash or reword your commit to make 'Redmine issues' happy :) |
@@ -229,25 +229,29 @@ def test_needs_publish | |||
:action => "publish") | |||
assert_equal @composite.needs_publish?, true | |||
@composite.create_new_version | |||
@composite.reload |
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.
Can create_new_version
somehow invalidate the latest_version_object
cache on the object?
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.
- Rails load the
@composite
content view. - Somewhere, latest_version_object is used and stored (and would be re-used later on)
- create_new_version creates a new version but the reference in the already loaded
@composite
is not updated.
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, I got that. That's why I was asking if you can somehow flush that cached latest_version_object
from Rails. Because I'm worried you might end up serving some outdated data somewhere. Looks like this is a Rails 7.1 feature: https://www.shakacode.com/blog/rails-7-1-allows-resetting-singular-associations/
So I think you can some something like:
# Rails 7.1+
reset_latest_version_object if respond_to?(:reset_latest_version_object)
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 seem to be on Rails 6.1.7.6. (I didn't think we had upgraded to 7.1 already..)
Anyway, reload
seems fine to me for the time being.
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 seem to be on Rails 6.1.7.6. (I didn't think we had upgraded to 7.1 already..)
Yes, we're not there yet. I wish we were, but not yet. We're working on it.
Anyway,
reload
seems fine to me for the time being.
My point was that this can also break things at runtime. Previously you could count on latest_version_object
being up to date, but after this it may be stale. For example, if a controller creates the new object and then uses latest_version_object
it will show the old data.
I don't know if that happens and if we have any coverage for it, but it's an API change that can be breaking.
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 it really necessary to reload it? AFAIK, if API / UI is used, you run a action, like "Create a new Version" and then you run another action - which would be a completely new request and therefore all the structure will be reloaded automatically. I think, we are trying to solve a "unit-test-issue" which doesn't occur in production.
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.
No, I'm not saying you need to call reload
. All I'm saying is that there is a cache invalidation that doesn't happen and that's a risk.
For example, if you have a REST API that is something like POST /content_views/:id/versions
(so effectively an API controller) and the implementation is roughly:
@content_view.create_new_version
{
'id' => @content_view.id,
'latest' => @content_view.latest_version_object,
}
Before this patch it would work. After this patch it would show incorrect data.
It would be very easy to do this, because the actual use is in RABL. Also note that there are other indirections, such as latest_version
and latest_version_id
. So these do show up here:
attributes :latest_version, :latest_version_id |
So all I'm saying is that we must verify such code doesn't exist, or if it does, deal with it. If it does exist, there is a very good chance there are no tests for such a thing, so it doesn't show up as a failure. It's very easy to introduce a regression here.
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.
So, should we:
- do a reload in create_new_version or
- run a reload after create_new_version in the tests?
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 think that from reading the source of the actions it's probably safe to assume it's not a problem, but I'd still leave at least a TODO comment for Rails 7.1 that it can safely invalidate the cached entry.
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 think all we're waiting on here is a TODO comment, right? |
8599f0e
to
3a75d1f
Compare
Broken React Test not related to this change. |
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.
LGTM pending green tests. Failures are unrelated but let's wait just to be safe.
[test katello] |
@sbernhard I think this may need another rebase due to the recent CI changes. |
actually no, it ain't a required check! Merging |
…atello#10865) (cherry picked from commit 4311086)
…atello#10865) (cherry picked from commit 4311086)
Strips away 480 sql queries because of needs_publish? and especially the implementation of latest_version_object
Display 20 Content Views on UI (index page)
Total amount of queries:
[root@or v2]# grep SELECT /tmp/cv_without_opt1.log | wc -l
1234
[root@or v2]# grep SELECT /tmp/cv_opt1.log | wc -l
755
[root@or v2]# grep SELECT /tmp/cv_without_opt1.log | grep content_view_version | wc -l
641
[root@or v2]# grep SELECT /tmp/cv_opt1.log | grep content_view_version | wc -l
181
Details: https://pawelurbanek.com/rails-eager-ordered (and thank you so much for this page)