From eef5a8400020d3e2eb07c17a9ca23c648091b8d4 Mon Sep 17 00:00:00 2001 From: Jon Guymon Date: Thu, 30 Aug 2012 17:02:41 -0700 Subject: [PATCH] RUBY-868 exclude Rails config from flat stack and make sure procs are properly handled --- lib/new_relic/agent/configuration/manager.rb | 23 +++++++++++++++----- lib/new_relic/agent/new_relic_service.rb | 8 +++++-- lib/new_relic/agent/pipe_channel_manager.rb | 11 +++++----- lib/new_relic/language_support.rb | 8 +++++++ 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/lib/new_relic/agent/configuration/manager.rb b/lib/new_relic/agent/configuration/manager.rb index 3517f4fb51..900220e736 100644 --- a/lib/new_relic/agent/configuration/manager.rb +++ b/lib/new_relic/agent/configuration/manager.rb @@ -61,12 +61,25 @@ def fetch(key) end def flattened_config - @config_stack.reverse.inject({}) do |flat,stack| - thawed_stack = stack.dup - thawed_stack.each do |k,v| - thawed_stack[k] = instance_eval(&v) if v.respond_to?(:call) + @config_stack.reverse.inject({}) do |flat,layer| + thawed_layer = layer.dup + thawed_layer.each do |k,v| + begin + thawed_layer[k] = instance_eval(&v) if v.respond_to?(:call) + rescue => e + NewRelic::Control.instance.log.debug("#{e.class.name} : #{e.message} - when calling Proc for config key #{k}") + thawed_layer[k] = nil + end + exclude_rails_config(thawed_layer, k) end - flat.merge(thawed_stack) + flat.merge(thawed_layer) + end + end + + def exclude_rails_config(hash, key) + if defined?(::Rails::Configuration) && + hash[key].kind_of?(::Rails::Configuration) + hash.reject!(key) end end diff --git a/lib/new_relic/agent/new_relic_service.rb b/lib/new_relic/agent/new_relic_service.rb index 2f89c667c8..5a1450f934 100644 --- a/lib/new_relic/agent/new_relic_service.rb +++ b/lib/new_relic/agent/new_relic_service.rb @@ -119,7 +119,9 @@ def invoke_remote(method, *args) # big payloads get all the compression possible, to stay under # the 2,000,000 byte post threshold def compress_data(object) - dump = Marshal.dump(object) + dump = NewRelic::LanguageSupport.with_cautious_gc do + Marshal.dump(object) + end dump_size = dump.size @@ -200,7 +202,9 @@ def decompress_response(response) # so we can handle it in nonlocally def check_for_exception(response) dump = decompress_response(response) - value = Marshal.load(dump) + value = NewRelic::LanguageSupport.with_cautious_gc do + Marshal.load(dump) + end raise value if value.is_a? Exception value end diff --git a/lib/new_relic/agent/pipe_channel_manager.rb b/lib/new_relic/agent/pipe_channel_manager.rb index 81a4f8ce42..c5c60477a7 100644 --- a/lib/new_relic/agent/pipe_channel_manager.rb +++ b/lib/new_relic/agent/pipe_channel_manager.rb @@ -41,7 +41,10 @@ def close def write(data) @out.close unless @out.closed? - @in << Marshal.dump(data) + "\n\n" + @in << NewRelic::LanguageSupport.with_cautious_gc do + Marshal.dump(data) + end + @in << "\n\n" end def read @@ -137,11 +140,7 @@ def merge_data_from_pipe(pipe_handle) end def unmarshal(data) - if NewRelic::LanguageSupport.broken_gc? - NewRelic::LanguageSupport.with_disabled_gc do - Marshal.load(data) - end - else + NewRelic::LanguageSupport.with_cautious_gc do Marshal.load(data) end rescue StandardError => e diff --git a/lib/new_relic/language_support.rb b/lib/new_relic/language_support.rb index 3598523548..8c3dd8f301 100644 --- a/lib/new_relic/language_support.rb +++ b/lib/new_relic/language_support.rb @@ -82,6 +82,14 @@ def with_disabled_gc end end + def with_cautious_gc + if broken_gc? + with_disabled_gc { yield } + else + yield + end + end + def using_version?(version) numbers = version.split('.') numbers == ::RUBY_VERSION.split('.')[0, numbers.size]