-
-
Notifications
You must be signed in to change notification settings - Fork 315
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
Eagerload at the controller or job layer #2313
Eagerload at the controller or job layer #2313
Conversation
b251b6f
to
4ea6672
Compare
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.
This is really great. I have a question about the publish job
b8dd989
to
77c3659
Compare
It's not great to eager load stuff at the model level. In case a previous user of the data has preloaded already, we're now preloading twice. Since preloading is expensive, we should avoid that and commit to only loading from model or service objects when there's no controller we can hook into.
77c3659
to
ac8555f
Compare
We need to preload a bit of stuff to publish a page, notably all the elements, ingredients, and related objects of its draft version. We probaly don´t need to load much of the public version, or any other versions, as those are not relevant to the operation.
Note that we're only preloading the public version here.
Here, we need to preload the draft version because that's what we look at.
This spec mocked many things unnecessarily.
Passing an page "object" here through `GlobalID` and then reloading will lead to double page loads.
1ac0d43
to
32d2b92
Compare
429f126
to
7e5268c
Compare
This helps keep the duplication down.
7e5268c
to
dbcfd93
Compare
Eagerload at the controller or job layer
@mamhoff We just upgraded to 6.0.12 from 4.0 and noticed a significant performance regression and it appears to be due to this change. We verified by temporarily rolling back to 6.0.5 and the previous response times returned. After we upgraded, we immediately noticed a lot more time spent in pg/postgres and that transactions were taking 2.5x as long overall at p50 in Datadog. Most of the requests we observe are just a small Alchemy page that's used as a health check. Therefore, the partials for this page are typically cached. It seems like even if we don't need to get any data, it's eagerly being loaded. There were originally some eager loading optimizations added in Alchemy 4.4 (#1674), but @tvdeyen mentioned there that eager loading was not added non-API HTML requests to avoid unnecessary work for cached pages. It appears that the performance slowdown I observed is related to that consideration where we now perform extra queries even if they wouldn't have been needed. However, on a cold cache, it does seem to improve performance. Maybe even adding nested elements could further reduce queries, but that's a separate question. Is it intended that we'll now have slower performance on cached page fragment hits? Is there any way to eager load, but only if the page isn't cached? |
@wuservices hey, thanks for bringing this to our attention. Would you be so kind and create a fresh Alchemy app where we can reproduce the problem? That would really help us to fix this, because - no - it is not intended to have slower performance 😏 cc @mamhoff |
@wuservices @mamhoff I created an issue to further discuss the problem |
What is this pull request for?
(Extracted from #2309)
This moves preloading of stuff to the Job layer rather than do it at the controller layer. Two advantages: We don't preload anything we don't need, and the element repository of the page version can be used in other contexts as well (I had a case where I wanted to load multiple pages and preload their ingredients, and using the previous element repository would break that).
Notable changes (remove if none)
We now also preload ingredients. We do that explicitly at the controller level, which means we can use the
PageVersion#element_repository
in contexts like the following:Checklist