class Hackle::EventDispatcher

Constants

DEFAULT_DISPATCH_QUEUE_CAPACITY
DEFAULT_DISPATCH_WORKER_SIZE

Public Class Methods

new(config:, sdk_info:) click to toggle source
# File lib/hackle/events/event_dispatcher.rb, line 9
def initialize(config:, sdk_info:)
  @logger = config.logger
  @client = HTTP.client(base_uri: config.event_uri)
  @headers = HTTP.sdk_headers(sdk_info: sdk_info)
  @dispatcher_executor = Concurrent::ThreadPoolExecutor.new(
    min_threads: DEFAULT_DISPATCH_WORKER_SIZE,
    max_threads: DEFAULT_DISPATCH_WORKER_SIZE,
    max_queue: DEFAULT_DISPATCH_QUEUE_CAPACITY
  )
end

Public Instance Methods

dispatch(events:) click to toggle source
# File lib/hackle/events/event_dispatcher.rb, line 20
def dispatch(events:)
  payload = create_payload(events: events)
  begin
    @dispatcher_executor.post { dispatch_payload(payload: payload) }
  rescue Concurrent::RejectedExecutionError
    @logger.warn { 'Dispatcher executor queue is full. Event dispatch rejected' }
  end
end
shutdown() click to toggle source
# File lib/hackle/events/event_dispatcher.rb, line 29
def shutdown
  @dispatcher_executor.shutdown
  unless @dispatcher_executor.wait_for_termination(10)
    @logger.warn { 'Failed to dispatch previously submitted events' }
  end
end

Private Instance Methods

create_exposure_event(exposure) click to toggle source

@param exposure [UserEvent::Exposure]

# File lib/hackle/events/event_dispatcher.rb, line 71
def create_exposure_event(exposure)
  {
    timestamp: exposure.timestamp,
    userId: exposure.user.id,
    experimentId: exposure.experiment.id,
    experimentKey: exposure.experiment.key,
    variationId: exposure.variation.id,
    variationKey: exposure.variation.key
  }
end
create_payload(events:) click to toggle source
# File lib/hackle/events/event_dispatcher.rb, line 51
def create_payload(events:)
  exposure_events = []
  track_events = []
  events.each do |event|
    case event
    when UserEvent::Exposure
      exposure_events << create_exposure_event(event)
    when UserEvent::Track
      track_events << create_track_event(event)
    end
  end
  {
    exposureEvents: exposure_events,
    trackEvents: track_events
  }
end
create_track_event(track) click to toggle source

@param track [UserEvent::Track]

# File lib/hackle/events/event_dispatcher.rb, line 85
def create_track_event(track)
  {
    timestamp: track.timestamp,
    userId: track.user.id,
    eventTypeId: track.event_type.id,
    eventTypeKey: track.event_type.key,
    value: track.event.value,
    properties: track.event.properties
  }
end
dispatch_payload(payload:) click to toggle source
# File lib/hackle/events/event_dispatcher.rb, line 38
def dispatch_payload(payload:)
  request = Net::HTTP::Post.new('/api/v1/events', @headers)
  request.content_type = 'application/json'
  request.body = payload.to_json

  response = @client.request(request)

  status_code = response.code.to_i
  HTTP.check_successful(status_code: status_code)
rescue => e
  @logger.error { "Failed to dispatch events: #{e.inspect}" }
end