lib/instana/agent.rb in instana-0.9.2 vs lib/instana/agent.rb in instana-0.10.1

- old
+ new

@@ -92,50 +92,63 @@ # Used post fork to re-initialize state and restart communications with # the host agent. # def after_fork - ::Instana.logger.debug "after_fork hook called. Falling back to unannounced state." + ::Instana.logger.debug "after_fork hook called. Falling back to unannounced state and spawning a new background agent thread." # Re-collect process information post fork @pid = Process.pid collect_process_info - # Set last snapshot to 10 minutes ago - # so we send a snapshot sooner than later - @last_snapshot = Time.now - 600 - transition_to(:unannounced) - start + setup + spawn_background_thread end + # Spawns the background thread and calls start. This method is separated + # out for those who wish to control which thread the background agent will + # run in. + # + # This method can be overridden with the following: + # + # module Instana + # class Agent + # def spawn_background_thread + # # start thread + # start + # end + # end + # end + # + def spawn_background_thread + # The thread calling fork is the only thread in the created child process. + # fork doesn’t copy other threads. + # Restart our background thread + Thread.new do + start + end + end + # Sets up periodic timers and starts the agent in a background thread. # - def start + def setup # The announce timer # We attempt to announce this ruby sensor to the host agent. # In case of failure, we try again in 30 seconds. @announce_timer = @timers.now_and_every(30) do - if forked? - after_fork - break - end if host_agent_ready? && announce_sensor - ::Instana.logger.debug "Announce successful. Switching to metrics collection." + ::Instana.logger.debug "Announce successful. Switching to metrics collection. pid: #{Process.pid}" transition_to(:announced) end end # The collect timer # If we are in announced state, send metric data (only delta reporting) # every ::Instana::Collector.interval seconds. @collect_timer = @timers.every(::Instana::Collector.interval) do if @state == :announced - if forked? - after_fork - break - end unless ::Instana::Collector.collect_and_report # If report has been failing for more than 1 minute, # fall back to unannounced state if (Time.now - @entity_last_seen) > 60 ::Instana.logger.debug "Metrics reporting failed for >1 min. Falling back to unannounced state." @@ -143,35 +156,48 @@ end end ::Instana.processor.send end end + end - # Start the background ruby sensor thread. It works off of timers and - # is sleeping otherwise - Thread.new do - loop { - if @state == :unannounced - @collect_timer.pause - @announce_timer.resume - else - @announce_timer.pause - @collect_timer.resume - end - @timers.wait - } + # Starts the timer loop for the timers that were initialized + # in the setup method. This is blocking and should only be + # called from an already initialized background thread. + # + def start + loop do + if @state == :unannounced + @collect_timer.pause + @announce_timer.resume + else + @announce_timer.pause + @collect_timer.resume + end + @timers.wait end + ensure + Instana.logger.debug "Agent start method exiting. state: #{@state} pid: #{Process.pid}" end # Indicates if the agent is ready to send metrics - # or data. + # and/or data. # def ready? # In test, we're always ready :-) return true if ENV['INSTANA_GEM_TEST'] + if forked? + ::Instana.logger.debug "Instana: detected fork. Calling after_fork" + after_fork + end + @state == :announced + rescue => e + Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" + Instana.logger.debug e.backtrace.join("\r\n") + return false end # Returns the PID that we are reporting to # def report_pid @@ -339,9 +365,13 @@ # Set last snapshot to 10 minutes ago # so we send a snapshot on first report @last_snapshot = Time.now - 601 when :unannounced @state = :unannounced + + # Set last snapshot to 10 minutes ago + # so we send a snapshot on first report + @last_snapshot = Time.now - 601 else ::Instana.logger.warn "Uknown agent state: #{state}" end end