Class: NewRelic::Agent::StatsEngine::MetricStats::SynchronizedHash
- Inherits:
-
Hash
- Object
- Hash
- NewRelic::Agent::StatsEngine::MetricStats::SynchronizedHash
- Defined in:
- lib/new_relic/agent/stats_engine/metric_stats.rb
Overview
A simple mutex-synchronized hash to make sure our statistics are internally consistent even in truly-threaded rubies like JRuby
Instance Attribute Summary collapse
-
#lock ⇒ Object
readonly
Returns the value of attribute lock.
Instance Method Summary collapse
- #[]=(*args) ⇒ Object
- #clear(*args) ⇒ Object
- #delete(*args) ⇒ Object
- #delete_if(*args) ⇒ Object
-
#initialize ⇒ SynchronizedHash
constructor
A new instance of SynchronizedHash.
- #initialize_copy(old) ⇒ Object
- #log_error(e) ⇒ Object
- #log_thread(t) ⇒ Object
- #reset ⇒ Object
Constructor Details
#initialize ⇒ SynchronizedHash
Returns a new instance of SynchronizedHash.
13 14 15 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 13 def initialize @lock = Mutex.new end |
Instance Attribute Details
#lock ⇒ Object (readonly)
Returns the value of attribute lock.
11 12 13 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 11 def lock @lock end |
Instance Method Details
#[]=(*args) ⇒ Object
24 25 26 27 28 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 24 def []=(*args) @lock.synchronize { super } rescue => e log_error(e) end |
#clear(*args) ⇒ Object
30 31 32 33 34 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 30 def clear(*args) @lock.synchronize { super } rescue => e log_error(e) end |
#delete(*args) ⇒ Object
36 37 38 39 40 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 36 def delete(*args) @lock.synchronize { super } rescue => e log_error(e) end |
#delete_if(*args) ⇒ Object
42 43 44 45 46 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 42 def delete_if(*args) @lock.synchronize { super } rescue => e log_error(e) end |
#initialize_copy(old) ⇒ Object
17 18 19 20 21 22 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 17 def initialize_copy(old) super old.each do |key, value| self.store(key, value.dup) end end |
#log_error(e) ⇒ Object
52 53 54 55 56 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 52 def log_error(e) backtraces = Thread.list.map { |t| log_thread(t) }.join("\n\n") NewRelic::Control.instance.log.warn( "SynchronizedHash failure: #{e.class.name}: #{e.}\n#{backtraces}") end |
#log_thread(t) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 58 def log_thread(t) # Ruby 1.8 doesn't expose backtrace properly, so make sure it's there if t.nil? || !t.respond_to?(:backtrace) || t.backtrace.nil? return "#{t}\n\tNo backtrace for thread" end backtrace = t.backtrace.map { |b| "\t#{b}" }.join("\n") "\t#{t}\n#{backtrace}" rescue Exception => e # JRuby 1.7.0 has a nasty habit of raising a # java.lang.NullPointerException when we iterate through threads # asking for backtraces. This line allows us to swallow java # exceptions without referencing their classes (since they don't # exist in MRI). It also prevents us from swallowing signals or # other nasty things that can happen when you rescue Exception. NewRelic::Control.instance.log.warn( "Error collecting thread backtraces: #{e.class.name}: #{e.}") NewRelic::Control.instance.log.debug( e.backtrace.join("\n") ) raise e if e.class.ancestors.include? Exception end |
#reset ⇒ Object
48 49 50 |
# File 'lib/new_relic/agent/stats_engine/metric_stats.rb', line 48 def reset values.each { |s| s.reset } end |