diff options
author | Jason Nochlin <hundredwatt@gmail.com> | 2015-02-07 15:33:13 -0500 |
---|---|---|
committer | Jason Nochlin <hundredwatt@users.noreply.github.com> | 2015-03-25 16:50:11 -0400 |
commit | 4d6fbe2934e94384e722ff6ca16e97c8978d4665 (patch) | |
tree | a00424fc01863d0c76c466cf33f692ebde67091e /activerecord/lib/active_record/relation | |
parent | 348377da4d623a81b570b2bf46e6ef9e5ee4e12f (diff) | |
download | rails-4d6fbe2934e94384e722ff6ca16e97c8978d4665.tar.gz rails-4d6fbe2934e94384e722ff6ca16e97c8978d4665.tar.bz2 rails-4d6fbe2934e94384e722ff6ca16e97c8978d4665.zip |
Add `config.active_record.warn_on_records_fetched_greater_than` option
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
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.
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r-- | activerecord/lib/active_record/relation/record_fetch_warning.rb | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/relation/record_fetch_warning.rb b/activerecord/lib/active_record/relation/record_fetch_warning.rb new file mode 100644 index 0000000000..0d31f73ddd --- /dev/null +++ b/activerecord/lib/active_record/relation/record_fetch_warning.rb @@ -0,0 +1,50 @@ +module ActiveRecord + class Relation + module RecordFetchWarning + # 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`, + # a warning is logged. This allows for the dection of queries that + # return a large number of records, which could cause memory + # bloat. + # + # In most cases, fetching large number of records can be performed + # efficiently using the ActiveRecord::Batches methods. + # See active_record/lib/relation/batches.rb for more information. + def exec_queries + QueryRegistry.reset + + super.tap do + if logger && warn_on_records_fetched_greater_than + if @records.length > warn_on_records_fetched_greater_than + logger.warn "Query fetched #{@records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}" + end + end + end + end + + ActiveSupport::Notifications.subscribe("sql.active_record") do |*args| + payload = args.last + + QueryRegistry.queries << payload[:sql] + end + + class QueryRegistry # :nodoc: + extend ActiveSupport::PerThreadRegistry + + attr_accessor :queries + + def initialize + reset + end + + def reset + @queries = [] + end + end + end + end +end + +ActiveRecord::Relation.prepend ActiveRecord::Relation::RecordFetchWarning |