From 3078c7d4ca345d2f114765039a88de2d5ae548dd Mon Sep 17 00:00:00 2001 From: Holger Just Date: Sat, 4 Feb 2017 01:04:18 +0100 Subject: [PATCH] Use a different BufferStack per thread That way, we can ensure that the BufferStack and the Buffers themselves including their nested fields can not be accessed by different threads, providing some thread safety for non malicious users. --- lib/rackstash/logger.rb | 5 ++++- spec/rackstash/logger_spec.rb | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/rackstash/logger.rb b/lib/rackstash/logger.rb index 5f82514..1dff721 100644 --- a/lib/rackstash/logger.rb +++ b/lib/rackstash/logger.rb @@ -3,6 +3,7 @@ # This software may be modified and distributed under the terms # of the MIT license. See the LICENSE.txt file for details. +require 'concurrent' require 'forwardable' require 'rackstash/buffer_stack' @@ -51,6 +52,8 @@ module Rackstash @level = DEBUG @progname = PROGNAME @formatter = Formatter.new + + @buffer_stack = Concurrent::ThreadLocalVar.new end # Set the base log level as either one of the {SEVERITIES} or a @@ -239,7 +242,7 @@ module Rackstash private def buffer_stack - @buffer_stack ||= Rackstash::BufferStack.new(@sink) + @buffer_stack.value ||= BufferStack.new(@sink) end def buffer diff --git a/spec/rackstash/logger_spec.rb b/spec/rackstash/logger_spec.rb index 733eac9..8a5135e 100644 --- a/spec/rackstash/logger_spec.rb +++ b/spec/rackstash/logger_spec.rb @@ -321,4 +321,18 @@ describe Rackstash::Logger do expect(messages.last).to include message: 'Unknown', severity: 5 end end + + context 'with multiple threads' do + it 'maintains thread-local stacks' do + first_stack = logger.send(:buffer_stack) + expect(first_stack).to be_a Rackstash::BufferStack + + Thread.new do + second_stack = logger.send(:buffer_stack) + expect(second_stack).to be_a Rackstash::BufferStack + + expect(second_stack).to_not eql first_stack + end.join + end + end end