From 96ab01e8f2b5a4475453acf60f9cf9bd8cd98483 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 18 Aug 2008 23:33:46 -0500 Subject: [PATCH] Maintain a seperate buffer for each thread --- .../lib/active_support/buffered_logger.rb | 19 +++++++----- activesupport/test/buffered_logger_test.rb | 29 ++++++++++++++++--- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb index cedc1afe7f..6553d72b4f 100644 --- a/activesupport/lib/active_support/buffered_logger.rb +++ b/activesupport/lib/active_support/buffered_logger.rb @@ -33,11 +33,10 @@ def silence(temporary_level = ERROR) attr_accessor :level attr_reader :auto_flushing - attr_reader :buffer def initialize(log, level = DEBUG) @level = level - @buffer = [] + @buffer = {} @auto_flushing = 1 @guard = Mutex.new @@ -60,9 +59,7 @@ def add(severity, message = nil, progname = nil, &block) # If a newline is necessary then create a new message ending with a newline. # Ensures that the original message is not mutated. message = "#{message}\n" unless message[-1] == ?\n - @guard.synchronize do - buffer << message - end + buffer << message auto_flush message end @@ -96,8 +93,8 @@ def auto_flushing=(period) def flush @guard.synchronize do unless buffer.empty? - old_buffer = @buffer - @buffer = [] + old_buffer = buffer + clear_buffer @log.write(old_buffer.join) end end @@ -113,5 +110,13 @@ def close def auto_flush flush if buffer.size >= @auto_flushing end + + def buffer + @buffer[Thread.current] ||= [] + end + + def clear_buffer + @buffer[Thread.current] = [] + end end end diff --git a/activesupport/test/buffered_logger_test.rb b/activesupport/test/buffered_logger_test.rb index 97649518b7..6319c09210 100644 --- a/activesupport/test/buffered_logger_test.rb +++ b/activesupport/test/buffered_logger_test.rb @@ -70,7 +70,7 @@ def test_should_not_mutate_message end @logger.flush - assert !@output.string.empty?, @logger.buffer.size + assert !@output.string.empty?, @logger.send(:buffer).size end define_method "test_disabling_auto_flush_with_#{disable.inspect}_should_flush_at_max_buffer_size_as_failsafe" do @@ -83,10 +83,10 @@ def test_should_not_mutate_message end @logger.info 'there it is.' - assert !@output.string.empty?, @logger.buffer.size + assert !@output.string.empty?, @logger.send(:buffer).size end end - + def test_should_know_if_its_loglevel_is_below_a_given_level ActiveSupport::BufferedLogger::Severity.constants.each do |level| @logger.level = ActiveSupport::BufferedLogger::Severity.const_get(level) - 1 @@ -105,7 +105,7 @@ def test_should_auto_flush_every_n_messages @logger.info 'there it is.' assert !@output.string.empty?, @output.string end - + def test_should_create_the_log_directory_if_it_doesnt_exist tmp_directory = File.join(File.dirname(__FILE__), "tmp") log_file = File.join(tmp_directory, "development.log") @@ -115,4 +115,25 @@ def test_should_create_the_log_directory_if_it_doesnt_exist ensure FileUtils.rm_rf(tmp_directory) end + + def test_logger_should_maintain_separate_buffers_for_each_thread + @logger.auto_flushing = false + + a = Thread.new do + @logger.info("a"); Thread.pass; + @logger.info("b"); Thread.pass; + @logger.info("c"); @logger.flush + end + + b = Thread.new do + @logger.info("x"); Thread.pass; + @logger.info("y"); Thread.pass; + @logger.info("z"); @logger.flush + end + + a.join + b.join + + assert_equal "a\nb\nc\nx\ny\nz\n", @output.string + end end -- GitLab