-
Notifications
You must be signed in to change notification settings - Fork 9
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
Perf: Better response times from api/public/v1/courses #4616
base: main
Are you sure you want to change the base?
Conversation
8abbd54
to
292ac6f
Compare
0d446ef
to
ef56808
Compare
9704bcc
to
fc4cec0
Compare
d20fbfb
to
7fa9ffd
Compare
7fa9ffd
to
ae1835b
Compare
fe1da53
to
90c5218
Compare
7e7bb71
to
2c61501
Compare
2c61501
to
3c2cf1f
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.
Niceee!! <3
Need to cache against all params
ef44f71
to
ec08b4d
Compare
return enrichments.select(&:last_published_timestamp_utc).max_by(&:last_published_timestamp_utc)&.last_published_timestamp_utc if enrichments.loaded? | ||
|
||
enrichments.maximum(:last_published_timestamp_utc) | ||
end |
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 looks like it can be generalised for all associations.
Have you considered looking into ActiveRecord/Associations/CollectionProxy? A #maximum
method there might be able to address this issue across the entire app with a single 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.
Yeah that looks tempting. but I would be careful about doing that. It's something we should discuss though, it seems like a useful thing to do.
def cached_course_count | ||
year = permitted_params[:recruitment_cycle_year] || RecruitmentCycle.current.year | ||
|
||
if permitted_params[:no_cache] |
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.
Below might be something for another PR.
It might be more conventional to read the Cache-Control
request header and return cached vs non-cached results.
I haven't quite dug into if that's indeed the right header, or what the header value should be (I think no-cache
?), and also if my assumption is considered standard practice, but it might be worth looking into.
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'm happy to remove this, I don't think it should be merged. Undocumented api params probably aren't a good idea.
As for the cache headers, I believe those (response headers) are for instructing how the client should cache, not how the server should respond.
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 this section is indicating that there are request header standards too, but yeah, I haven't seen it in practice yet. I wonder how the browser implements the "Disable cache" checkbox.
But yeah, I agree. Let's remove the no_cache
for now.
ec08b4d
to
57a9250
Compare
def cached_course_count | ||
year = permitted_params[:recruitment_cycle_year] || RecruitmentCycle.current.year | ||
|
||
Rails.cache.fetch("api_course_count_#{year}", expires_in: 5.minutes) do |
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.
Let's have a discussion about this expiration time?
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.
Everything looks good. Great initiative. ✌️
Let's have a separate discussion about the cache & expiration.
Context
Counting the number of courses in a recruitment cycle is very expensive. We do this on every request to the courses endpoint.
This is an "agonising" endpoint in Skylight
Loadtesting the change
The tests were run with Siege.
Siege documentation
All tests were run against review apps. The review apps all had 1 replica with 512MiB memory.
Before changes
With just
loaded?
changesWith count query cached and
loaded?
changesResult
The URLs
The URLs used were variations on this list.
I added
no_cache
for the "no cache" test run.I changed the PR number for the "original" test run.
Changes proposed in this pull request
loaded?
to avoid making requests to the database when we already have records in memory.filter
field is not used in the cache key because it is ignored in the query. The API does not filter courses.Guidance to review
Things to check