Skip to content

Commit

Permalink
Maintain a seperate buffer for each thread
Browse files Browse the repository at this point in the history
  • Loading branch information
josh committed Aug 19, 2008
1 parent c1a8690 commit 96ab01e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
19 changes: 12 additions & 7 deletions activesupport/lib/active_support/buffered_logger.rb
Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
29 changes: 25 additions & 4 deletions activesupport/test/buffered_logger_test.rb
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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")
Expand All @@ -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

0 comments on commit 96ab01e

Please sign in to comment.