class Sqreen::EcosystemIntegration::RequestLifecycleTracking

This class gets notified of request start/end and 1) distributes such events to listeners (typically ecosystem modules;

the method add_start_observer is exposed to ecosystem modules through
+Sqreen::Ecosystem::ModuleApi::EventListener+ and the dispatch table).

2) keeps track of whether a request is active on this thread. This is

so that users of this class can have this information without needing
to subscribe to request start/events and keeping thread local state
themselves.

XXX: Since the Ecosystem is also notified of request start/end, it could notify its modules of request start without going through the dispatch table and call add_start_observer. We need to think if we want to keep the transaction / request distinction or if they should just be assumed to be the same, though.

Public Class Methods

new() click to toggle source
# File lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb, line 27
def initialize
  @start_observers = []
  @tl_key = "#{object_id}_req_in_flight"
end

Public Instance Methods

add_start_observer(cb) click to toggle source

@param cb A callback taking a Rack::Request

# File lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb, line 35
def add_start_observer(cb)
  @start_observers << cb
end
in_request?() click to toggle source
# File lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb, line 39
def in_request?
  Thread.current[@tl_key] ? true : false
end
notify_request_end() click to toggle source
# File lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb, line 58
def notify_request_end
  Thread.current[@tl_key] = false
end
notify_request_start(rack_req) click to toggle source

API for classes notifying this one of request events

# File lib/sqreen/ecosystem_integration/request_lifecycle_tracking.rb, line 45
def notify_request_start(rack_req)
  Thread.current[@tl_key] = true
  return if @start_observers.empty?
  @start_observers.each do |cb|
    begin
      cb.call(rack_req)
    rescue ::Exception => e # rubocop:disable Lint/RescueException
      logger.warn { "Error calling #{cb} on request start: #{e.message}" }
      Sqreen::RemoteException.record(e)
    end
  end
end