From 1787e094ecf8996bf5125bcd929789783d22b0d3 Mon Sep 17 00:00:00 2001 From: Kyrylo Silin Date: Wed, 26 Feb 2020 18:49:43 +0800 Subject: [PATCH] stat: synchronize `to_h` with `increment_ms` Possibly fixes #545 (>4.4.0 <=4.13.0 causing RuntimeError: can't add a new key into hash during iteration) --- lib/airbrake-ruby/stat.rb | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/airbrake-ruby/stat.rb b/lib/airbrake-ruby/stat.rb index 3fe414d3..cc52b1bd 100644 --- a/lib/airbrake-ruby/stat.rb +++ b/lib/airbrake-ruby/stat.rb @@ -24,18 +24,21 @@ def initialize(sum: 0.0, sumsq: 0.0, tdigest: TDigest.new(0.05)) @sum = sum @sumsq = sumsq @tdigest = tdigest + @mutex = Mutex.new end # @return [Hash{String=>Object}] stats as a hash with compressed TDigest # (serialized as base64) def to_h - tdigest.compress! - { - 'count' => tdigest.size, - 'sum' => sum, - 'sumsq' => sumsq, - 'tdigest' => Base64.strict_encode64(tdigest.as_small_bytes), - } + @mutex.synchronize do + tdigest.compress! + { + 'count' => tdigest.size, + 'sum' => sum, + 'sumsq' => sumsq, + 'tdigest' => Base64.strict_encode64(tdigest.as_small_bytes), + } + end end # Increments tdigest timings and updates tdigest with the difference between @@ -45,8 +48,10 @@ def to_h # @param [Date] end_time # @return [void] def increment(start_time, end_time = nil) - end_time ||= Time.new - increment_ms((end_time - start_time) * 1000) + @mutex.synchronize do + end_time ||= Time.new + increment_ms((end_time - start_time) * 1000) + end end # Increments tdigest timings and updates tdigest with given +ms+ value. @@ -54,10 +59,12 @@ def increment(start_time, end_time = nil) # @param [Float] ms # @return [void] def increment_ms(ms) - self.sum += ms - self.sumsq += ms * ms + @mutex.synchronize do + self.sum += ms + self.sumsq += ms * ms - tdigest.push(ms) + tdigest.push(ms) + end end # We define custom inspect so that we weed out uninformative TDigest, which