From 2e5a6b3b6b7e52be5cf10573af087dd23d1c57cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Fran=C3=A7a?= Date: Wed, 24 Jul 2019 16:28:56 -0400 Subject: [PATCH] Merge pull request #36753 from cmrd-senya/36752-make-rails-logger-fiber-safe Make ActiveSupport::Logger Fiber-safe --- activesupport/CHANGELOG.md | 33 ++++++++++++++ .../logger_thread_safe_level.rb | 3 +- activesupport/test/logger_test.rb | 44 +++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 7f26ebf92b..08adbd6bb7 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,36 @@ +* Make ActiveSupport::Logger Fiber-safe. Fixes #36752. + + Use `Fiber.current.__id__` in `ActiveSupport::Logger#local_level=` in order + to make log level local to Ruby Fibers in addition to Threads. + + Example: + + logger = ActiveSupport::Logger.new(STDOUT) + logger.level = 1 + p "Main is debug? #{logger.debug?}" + + Fiber.new { + logger.local_level = 0 + p "Thread is debug? #{logger.debug?}" + }.resume + + p "Main is debug? #{logger.debug?}" + + Before: + + Main is debug? false + Thread is debug? true + Main is debug? true + + After: + + Main is debug? false + Thread is debug? true + Main is debug? false + + *Alexander Varnin* + + ## Rails 5.2.3 (March 27, 2019) ## * Add `ActiveSupport::HashWithIndifferentAccess#assoc`. diff --git a/activesupport/lib/active_support/logger_thread_safe_level.rb b/activesupport/lib/active_support/logger_thread_safe_level.rb index ba32813d3d..52295d7d33 100644 --- a/activesupport/lib/active_support/logger_thread_safe_level.rb +++ b/activesupport/lib/active_support/logger_thread_safe_level.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "active_support/concern" +require "fiber" module ActiveSupport module LoggerThreadSafeLevel # :nodoc: @@ -11,7 +12,7 @@ def after_initialize end def local_log_id - Thread.current.__id__ + Fiber.current.__id__ end def local_level diff --git a/activesupport/test/logger_test.rb b/activesupport/test/logger_test.rb index 5efbd10a7d..1df61a479f 100644 --- a/activesupport/test/logger_test.rb +++ b/activesupport/test/logger_test.rb @@ -257,6 +257,50 @@ def test_logger_level_local_thread_safety assert_level(Logger::INFO) end + def test_logger_level_main_fiber_safety + @logger.level = Logger::INFO + assert_level(Logger::INFO) + + fiber = Fiber.new do + assert_level(Logger::INFO) + end + + @logger.silence(Logger::ERROR) do + assert_level(Logger::ERROR) + fiber.resume + end + end + + def test_logger_level_local_fiber_safety + @logger.level = Logger::INFO + assert_level(Logger::INFO) + + another_fiber = Fiber.new do + @logger.silence(Logger::ERROR) do + assert_level(Logger::ERROR) + @logger.silence(Logger::DEBUG) do + assert_level(Logger::DEBUG) + end + end + + assert_level(Logger::INFO) + end + + Fiber.new do + @logger.silence(Logger::ERROR) do + assert_level(Logger::ERROR) + @logger.silence(Logger::DEBUG) do + another_fiber.resume + assert_level(Logger::DEBUG) + end + end + + assert_level(Logger::INFO) + end.resume + + assert_level(Logger::INFO) + end + private def level_name(level) ::Logger::Severity.constants.find do |severity| -- GitLab