module Sqreen::Dependency::Detector

Public Instance Methods

hook(&block) click to toggle source
# File lib/sqreen/dependency/detector.rb, line 36
def hook(&block)
  Sqreen.log.debug "[#{Process.pid}] Startup command: #{$0}"

  # ensure middleware presence

  ActiveSupport.on_load(:before_initialize, :yield => true) do
    Sqreen::Dependency::Rails.insert_sqreen_middlewares
  end if Sqreen::Dependency::Rails.required?

  Sqreen::Graft::Hook.add('Rack::Builder#to_app', to_app_hook_strategy) do
    after do
      Sqreen::Dependency::Rails.inspect_middlewares
    end
  end if Sqreen::Dependency::Rails.required?

  Sqreen::Graft::Hook.add('Sinatra::Base.setup_middleware') do
    after do |call|
      args = call.args

      Sqreen::Dependency::Sinatra.insert_sqreen_middlewares(args.first)
    end
  end.install if Sqreen::Dependency::Sinatra.required?

  Sqreen::Graft::Hook.add('Rack::Builder#to_app', to_app_hook_strategy) do
    after do |call|
      builder = call.instance

      Sqreen::Dependency::Sinatra.inspect_middlewares(builder)
    end
  end if Sqreen::Dependency::Sinatra.required?

  # ensure startup of thread in request handling processes

  Sqreen::Graft::Hook.add('Rack::Builder#to_app', to_app_hook_strategy) do
    after do |call|
      callback = call.callback

      Sqreen.log.debug "[#{Process.pid}] Start mode #{Sqreen::Dependency::Detector.start_mode}"
      if Sqreen::Dependency::Detector.start_mode == :rails || Sqreen::Dependency::Detector.start_mode == :rackup

        Sqreen::Dependency::Rack.find_handler do |handler|
          Sqreen::Dependency::Rack.on_run(handler) do
            case handler.name
            when 'Rack::Handler::Puma'
              Sqreen::Graft::Hook.add('Puma::Launcher#run') do
                before do
                  # HACK: Puma master? hack falls apart when not preloading
                  # it would think master is not, triggering startup
                  Sqreen::WebServer.instance_eval { @master_pid = Process.pid }
                  block.call
                  # HACK: because to_app callback is disabled, so won't run again in fork
                  if Sqreen::WebServer.forking? && !Sqreen::WebServer.preload_app?
                    Sqreen::WebServer.after_fork { block.call }
                  end
                end
              end
              Sqreen::Graft::Hook['Puma::Launcher#run'].install
            when 'Rack::Handler::PhusionPassenger'
              # noop, passenger will start his own separate process
              Sqreen.log.debug "[#{Process.pid}] Passenger will start in standalone process"
            when 'Rack::Handler::Unicorn' # unicorn-rails
              Sqreen::Graft::Hook.add('Unicorn::HttpServer.new') do
                before do
                  # BUG: detects single process...
                end
              end.install
            else
              block.call
            end
          end
        end
      else
        block.call
      end

      # #to_app can be called multiple times, run callback once only
      callback.disable
    end
  end

  Sqreen::Graft::Hook['Rack::Builder#to_app'].install

  # Sqreen::Graft::Hook.add('Rails::Server#start') do
  #   before { }
  # end
  # Sqreen::Graft::Hook['Rails::Server#start'].install
  # /!\ double instrument Rails < Rack => Rails.start_with -> Rails.start_without -> super -> Rack.start_with -> Rails.start_without
end
start_mode() click to toggle source
# File lib/sqreen/dependency/detector.rb, line 18
def start_mode
  if Sqreen::Dependency::Rails.server?
    :rails
  elsif Sqreen::Dependency::Rack.rackup?
    :rackup
  else
    :default
  end
end
to_app_hook_strategy() click to toggle source
# File lib/sqreen/dependency/detector.rb, line 28
def to_app_hook_strategy
  if Sqreen::Dependency::NewRelic.bundled? || Sqreen::Dependency::NewRelic.required?
    :chain
  else
    :prepend
  end
end