1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Make AS::Deprecation.silence block thread-local

Previouly `ActiveSupport::Deprecation.silence { ... }` would silence
deprecations from all threads, which I think is undesirable in a
mutli-threaded environment.

This leaves `ActiveSupport::Deprecation.silenced=` as setting a global
option, which might be a little confusing, but I think that these are
used in different ways, and this best preserves how they are generally
used. `silence {}` is used to silence a small section of code,
`silenced=` is usually used to set a default in an initializer or test
helper.

I somewhat think that `ActiveSupport::Deprecation.silenced=` should be
deprecated in favour of `ActiveSupport::Deprecation.behavior = :silence`
This commit is contained in:
John Hawthorn 2019-10-25 15:53:03 -07:00
parent 54f3e67172
commit b400e70a00
3 changed files with 36 additions and 6 deletions

View file

@ -41,6 +41,7 @@ module ActiveSupport
# By default, warnings are not silenced and debugging is off.
self.silenced = false
self.debug = false
@silenced_thread = Concurrent::ThreadLocalVar.new(false)
end
end
end

View file

@ -6,7 +6,7 @@ module ActiveSupport
class Deprecation
module Reporting
# Whether to print a message (silent mode)
attr_accessor :silenced
attr_writer :silenced
# Name of gem where method is deprecated
attr_accessor :gem_name
@ -33,11 +33,12 @@ module ActiveSupport
# ActiveSupport::Deprecation.warn('something broke!')
# end
# # => nil
def silence
old_silenced, @silenced = @silenced, true
yield
ensure
@silenced = old_silenced
def silence(&block)
@silenced_thread.bind(true, &block)
end
def silenced
@silenced || @silenced_thread.value
end
def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil)

View file

@ -290,6 +290,34 @@ class DeprecationTest < ActiveSupport::TestCase
ActiveSupport::Deprecation.silenced = false
end
def test_silence_threaded
barrier = Concurrent::CyclicBarrier.new(2)
th = Thread.new do
ActiveSupport::Deprecation.silence do
barrier.wait
barrier.wait
assert_not_deprecated { ActiveSupport::Deprecation.warn "abc" }
end
assert_deprecated("abc") { ActiveSupport::Deprecation.warn "abc" }
end
barrier.wait
assert_deprecated("abc") { ActiveSupport::Deprecation.warn "abc" }
ActiveSupport::Deprecation.silence do
assert_not_deprecated { ActiveSupport::Deprecation.warn "abc" }
end
assert_deprecated("abc") { ActiveSupport::Deprecation.warn "abc" }
barrier.wait
th.join
ensure
th.kill
end
def test_deprecation_without_explanation
assert_deprecated { @dtc.a }
assert_deprecated { @dtc.b }