Allow entirely opting out of deprecation warnings

Previously if you did `app.config.active_support.deprecation = :silence`, some work would still be done on each call to `ActiveSupport::Deprecation.warn`. Specifically [checking the backtrace](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L21)), generating the [deprecation warning](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L22)), and [checking if the warning is disallowed](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L23)).

In very hot paths, this could cause performance issues. This PR lets you turn off deprecation reporting entirely for a specific environment.

```ruby
config.active_support.report_deprecations = false
```

^ so has the same outcome as:

```ruby
config.active_support.deprecation = :silence
config.active_support.disallowed_deprecation = :silence
```

But it will short circuit [here](12372c5482/activesupport/lib/active_support/deprecation/reporting.rb (L19)).
This commit is contained in:
Alex Ghiculescu 2021-07-29 15:02:51 -05:00
parent c166b3b64a
commit ea3185ebdd
7 changed files with 66 additions and 28 deletions

View File

@ -1,3 +1,26 @@
* Allow entirely opting out of deprecation warnings
Previously if you did `app.config.active_support.deprecation = :silence`, some work would
still be done on each call to `ActiveSupport::Deprecation.warn`. In very hot paths, this could
cause performance issues.
Now, you can make `ActiveSupport::Deprecation.warn` a no-op:
```ruby
config.active_support.report_deprecations = false
```
This is the default in production for new apps. It is the equivalent to:
```ruby
config.active_support.deprecation = :silence
config.active_support.disallowed_deprecation = :silence
```
but will take a more optimised code path.
*Alex Ghiculescu*
* Faster tests by parallelizing only when overhead is justified by the number
of them.

View File

@ -54,7 +54,7 @@ module ActiveSupport
# [+stderr+] Log all deprecation warnings to <tt>$stderr</tt>.
# [+log+] Log all deprecation warnings to +Rails.logger+.
# [+notify+] Use +ActiveSupport::Notifications+ to notify +deprecation.rails+.
# [+silence+] Do nothing.
# [+silence+] Do nothing. On Rails, set `config.active_support.report_deprecations = false` to disable all behaviors.
#
# Setting behaviors only affects deprecations that happen after boot time.
# For more information you can read the documentation of the +behavior=+ method.
@ -93,6 +93,9 @@ module ActiveSupport
# ActiveSupport::Deprecation.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
# # custom stuff
# }
#
# If you are using Rails, you can set `config.active_support.report_deprecations = false` to disable
# all deprecation behaviors. This is similar to the `silence` option but more performant.
def behavior=(behavior)
@behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
end

View File

@ -39,16 +39,22 @@ module ActiveSupport
end
initializer "active_support.deprecation_behavior" do |app|
if deprecation = app.config.active_support.deprecation
ActiveSupport::Deprecation.behavior = deprecation
end
if app.config.active_support.report_deprecations == false
ActiveSupport::Deprecation.silenced = true
ActiveSupport::Deprecation.behavior = :silence
ActiveSupport::Deprecation.disallowed_behavior = :silence
else
if deprecation = app.config.active_support.deprecation
ActiveSupport::Deprecation.behavior = deprecation
end
if disallowed_deprecation = app.config.active_support.disallowed_deprecation
ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
end
if disallowed_deprecation = app.config.active_support.disallowed_deprecation
ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
end
if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
end
end
end

View File

@ -298,8 +298,12 @@ class DeprecationTest < ActiveSupport::TestCase
end
ActiveSupport::Deprecation.silenced = true
assert ActiveSupport::Deprecation.silenced
assert_not_deprecated { @dtc.partially }
ActiveSupport::Deprecation.silenced = false
assert_not ActiveSupport::Deprecation.silenced
end
def test_silence_threaded

View File

@ -922,20 +922,18 @@ There are a few configuration options available in Active Support:
* `config.active_support.cache_format_version` specifies which version of the cache serializer to use. Possible values are `6.1` and `7.0`.
* `config.active_support.deprecation` configures the behavior of deprecation warnings. The options are `:raise`, `:stderr`, `:log`, `:notify`, or `:silence`. The default is `:stderr`. Alternatively, you can set `ActiveSupport::Deprecation.behavior`.
* `config.active_support.disallowed_deprecation` configures the behavior of disallowed deprecation warnings. The options are `:raise`, `:stderr`, `:log`, `:notify`, or `:silence`. The default is `:raise`. Alternatively, you can set `ActiveSupport::Deprecation.disallowed_behavior`.
* `config.active_support.disallowed_deprecation_warnings` configures deprecation warnings that the Application considers disallowed. This allows, for example, specific deprecations to be treated as hard failures. Alternatively, you can set `ActiveSupport::Deprecation.disallowed_warnings`.
* `config.active_support.report_deprecations` allows you to disable all deprecation warnings (including disallowed deprecations); it makes `ActiveSupport::Deprecation.warn` a no-op. This is enabled by default in production.
* `ActiveSupport::Logger.silencer` is set to `false` to disable the ability to silence logging in a block. The default is `true`.
* `ActiveSupport::Cache::Store.logger` specifies the logger to use within cache store operations.
* `ActiveSupport::Deprecation.behavior` alternative setter to `config.active_support.deprecation` which configures the behavior of deprecation warnings for Rails.
* `ActiveSupport::Deprecation.disallowed_behavior` alternative setter to `config.active_support.disallowed_deprecation` which configures the behavior of disallowed deprecation warnings for Rails.
* `ActiveSupport::Deprecation.disallowed_warnings` alternative setter to `config.active_support.disallowed_deprecation_warnings` which configures deprecation warnings that the Application considers disallowed. This allows, for example, specific deprecations to be treated as hard failures.
* `ActiveSupport::Deprecation.silence` takes a block in which all deprecation warnings are silenced.
* `ActiveSupport::Deprecation.silenced` sets whether or not to display deprecation warnings. The default is `false`.
* `ActiveSupport.utc_to_local_returns_utc_offset_times` configures
`ActiveSupport::TimeZone.utc_to_local` to return a time with a UTC offset
instead of a UTC time incorporating that offset.
@ -1673,7 +1671,7 @@ Below is a comprehensive list of all the initializers found in Rails in the orde
* `i18n.callbacks`: In the development environment, sets up a `to_prepare` callback which will call `I18n.reload!` if any of the locales have changed since the last request. In production this callback will only run on the first request.
* `active_support.deprecation_behavior`: Sets up deprecation reporting for environments, defaulting to `:log` for development, `:notify` for production, and `:stderr` for test. If a value isn't set for `config.active_support.deprecation` then this initializer will prompt the user to configure this line in the current environment's `config/environments` file. Can be set to an array of values. This initializer also sets up behaviors for disallowed deprecations, defaulting to `:raise` for development and test and `:log` for production. Disallowed deprecation warnings default to an empty array.
* `active_support.deprecation_behavior`: Sets up deprecation reporting for environments, defaulting to `:log` for development, `:silence` for production, and `:stderr` for test. Can be set to an array of values. This initializer also sets up behaviors for disallowed deprecations, defaulting to `:raise` for development and test and `:silence` for production. Disallowed deprecation warnings default to an empty array.
* `active_support.initialize_time_zone`: Sets the default time zone for the application based on the `config.time_zone` setting, which defaults to "UTC".

View File

@ -84,14 +84,8 @@ Rails.application.configure do
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Log disallowed deprecations.
config.active_support.disallowed_deprecation = :log
# Tell Active Support which deprecation messages to disallow.
config.active_support.disallowed_deprecation_warnings = []
# Don't log any deprecations.
config.active_support.report_deprecations = false
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new

View File

@ -3459,6 +3459,16 @@ module ApplicationTests
assert_equal true, ActiveSupport::TimeWithZone.methods(false).include?(:name)
end
test "can entirely opt out of ActiveSupport::Deprecations" do
add_to_config "config.active_support.report_deprecations = false"
app "production"
assert_equal true, ActiveSupport::Deprecation.silenced
assert_equal [ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:silence]], ActiveSupport::Deprecation.behavior
assert_equal [ActiveSupport::Deprecation::DEFAULT_BEHAVIORS[:silence]], ActiveSupport::Deprecation.disallowed_behavior
end
private
def set_custom_config(contents, config_source = "custom".inspect)
app_file "config/custom.yml", contents