-
Notifications
You must be signed in to change notification settings - Fork 21.9k
Add config.active_record.warn_on_records_fetched_greater_than
option
#18846
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
Add config.active_record.warn_on_records_fetched_greater_than
option
#18846
Conversation
4e52ea1
to
88ba6ec
Compare
mattr_accessor :warn_on_result_set_size, instance_writer: false | ||
self.warn_on_result_set_size = nil | ||
|
||
|
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 line
88ba6ec
to
79e8929
Compare
@kaspth ✂️-ed |
Wondering if we should move the |
I don't think you need to touch the existing #exec_queries method. You could try the module approach using #prepend. Unless #prepend is frowned upon in Rails, which I need someone else to verify. |
I had the same thought, however there's no other use of |
Gave |
Nevermind comment about CI, travis-ci matrix is only Ruby 2.2 now. |
require 'models/post' | ||
require 'models/comment' | ||
require 'models/author' | ||
require 'models/rating' |
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 we remove the requires for the other models?
c5751fe
to
7bd96e4
Compare
I think you need to rebase this on master before Travis will try a build. |
Otherwise the code looks good to me 👍. It depends on whether others are okay with the initializer approach here. |
7bd96e4
to
12e2561
Compare
Thanks for feedback @kaspth 😄. Will await additional feedback and then can squash before merging. |
Sure thing 😄 Your test leaks state. The module you prepend is still in I don't know if unprepending a module is considered a dirty practice, so let's wait for others to chime in 😁 |
What you did just now is probably fine too :) |
@kaspth 👍 |
Just patched Delayed Job in a production Rails app with this warning and set up a log alert. Already found an instance of
|
Cool! I think the error message needs a little tweaking to read a bit more naturally. Would it be of use to broadcast this as an Active Support notification too? |
@@ -102,6 +102,17 @@ class Railtie < Rails::Railtie # :nodoc: | |||
end | |||
end | |||
|
|||
initializer "active_record.warn_on_result_set_size" do | |||
if config.active_record.warn_on_result_set_size | |||
config.after_initialize do |app| |
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.
Why we need the after_initialize
block?
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's not needed, its only there because I copied and pasted from the previous initializer
, doh! Will remove
3e9d3da
to
6aaf751
Compare
I've been thinking about the config option name and |
super.tap do | ||
if logger && warn_on_result_set_size | ||
if @records.length >= warn_on_result_set_size | ||
logger.warn "Result set size exceeded #{warn_on_result_set_size} (model: #{@klass}, records: #{@records.size})" |
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.
What about changing the message to something like:
"Large query detected. Exceeded #{warn_on_result_set_size} threshold by loading #{@records.size} #{@klass} records."
@kaspth I like where you're going. How about: For the config setting: For the message: "Large query detected. Exceeded #{warn_on_result_set_size} threshold by fetching #{@records.size} #{@klass} records." For the module, maybe we can call it |
I like your suggestions way better than I have some more thoughts about the warning message. There's a part of me that feels fetching is to lightweight a word. Is there a word that better fits we're dealing with a large query? I think we should explain the threshold just a bit more. Something like this reads a bit broken: |
Agreed, I'm struggling with how to phrase this 😄. Here's a number of ideas:
Alternatively, do we need to re-state the configured value by including
or maybe have a recommendation?:
Do any of those options resonate with you? |
Additionally, we could probably use AS::Notifications to capture the SQL query itself and include it in the warning. I'll play with that. |
d7d676d
to
24d6b9f
Compare
Well done and thanks for the kind words 👍 I'm going to need someone else to look through the notification stuff, so feel free to jump in. |
ee2af4b
to
b1b0cb4
Compare
I squashed my previous commits and fixed the documentation as per @fxn's recommendation |
# When this module is prepended to ActiveRecord::Relation and | ||
# `config.active_record.warn_on_records_fetched_greater_than` is | ||
# set to an integer, if the number of records a query returns is | ||
# greater than the value of `warn_on_records_fetched_greater_than`, |
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.
Your documentation says greater than but the check is >=
😉
1c6f28f
to
3c6675c
Compare
@hundredwatt hey, completely forgot about this until today 😄 Can you rebase and squash your commits? Then this gets my 👍 Great work, ❤️ |
3c6675c
to
613abe2
Compare
When set to an integer, a warning will be logged whenever a result set larger than the specified size is returned by a query. Fixes rails#16463 The warning is outputed a module which is prepended in an initializer, so there will be no performance impact if `config.active_record.warn_on_records_fetched_greater_than` is not set.
613abe2
to
4d6fbe2
Compare
@kaspth No worries, I know there's a lot of other PRs out there 😉 I rebased/squashed, but the Travis build didn't kick off. Any ideas? |
@kaspth Nevermind, its building now |
payload = args.last | ||
|
||
QueryRegistry.queries << payload[:sql] | ||
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.
Could accomplish the same thing with:
ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
QueryRegistry.queries << payload[:sql]
end
The build passed, but I don't know why GitHub didn't signal anything here. |
¯_(ツ)_/¯ |
Add `config.active_record.warn_on_result_set_size` option
config.active_record.warn_on_result_set_size
optionconfig.active_record.warn_on_records_fetched_greater_than
option
Add `config.active_record.warn_on_records_fetched_greater_than` to the Configuring Rails Guide.
[skip ci] Update configuring.md with #18846
@kaspth @rafaelfranca Thanks so much for your feedback! 😄 💙 |
# `config.active_record.warn_on_records_fetched_greater_than` is | ||
# set to an integer, if the number of records a query returns is | ||
# greater than the value of `warn_on_records_fetched_greater_than`, | ||
# a warning is logged. This allows for the dection of queries that |
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.
s/dection/detection/
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 change was merged a while ago and after looking at the master branch I see it's already fixed: fe6de0f 😁
When set to an integer, a warning will be logged whenever a result set
larger than the specified size is returned by a query. Fixes #16463