class WarmBlanket::Orchestrator

Orchestrates threads to wait for the port to open and to perform the warmup requests

Constants

DEFAULT_HEADERS

Attributes

endpoints[R]
hostname[R]
logger[R]
port[R]
requester_factory[R]
wait_for_port_factory[R]
warmup_deadline[R]
warmup_threads[R]

Public Class Methods

new( requester_factory: Requester, wait_for_port_factory: WaitForPort, logger: WarmBlanket.config.logger, endpoints: WarmBlanket.config.endpoints, hostname: 'localhost', port: WarmBlanket.config.port, warmup_threads: WarmBlanket.config.warmup_threads, warmup_time_seconds: WarmBlanket.config.warmup_time_seconds ) click to toggle source
# File lib/warm_blanket/orchestrator.rb, line 47
def initialize(
  requester_factory: Requester,
  wait_for_port_factory: WaitForPort,
  logger: WarmBlanket.config.logger,
  endpoints: WarmBlanket.config.endpoints,
  hostname: 'localhost',
  port: WarmBlanket.config.port,
  warmup_threads: WarmBlanket.config.warmup_threads,
  warmup_time_seconds: WarmBlanket.config.warmup_time_seconds
)
  raise "Warmup threads cannot be less than 1 (got #{warmup_threads})" if warmup_threads < 1

  @requester_factory = requester_factory
  @wait_for_port_factory = wait_for_port_factory
  @logger = logger
  @endpoints = endpoints
  @hostname = hostname
  @port = port
  @warmup_threads = warmup_threads
  @warmup_deadline = Time.now + warmup_time_seconds
end

Public Instance Methods

call() click to toggle source
# File lib/warm_blanket/orchestrator.rb, line 69
def call
  safely_spawn_thread do
    logger.debug 'Started orchestrator thread'
    orchestrate
  end
end

Private Instance Methods

orchestrate() click to toggle source
# File lib/warm_blanket/orchestrator.rb, line 89
def orchestrate
  success = wait_for_port_to_open

  spawn_warmup_threads if success
end
perform_warmup_requests() click to toggle source
# File lib/warm_blanket/orchestrator.rb, line 111
def perform_warmup_requests
  success = false

  if Time.now >= warmup_deadline
    logger.warn "Warmup deadline already passed, will skip warmup"
    return
  end

  logger.debug "Starting warmup requests (remaining deadline: #{[warmup_deadline - Time.now, 0].max})"

  requester = requester_factory.new(
    base_url: "http://#{hostname}:#{port}",
    default_headers: DEFAULT_HEADERS,
    endpoints: endpoints,
  )

  while Time.now < warmup_deadline
    requester.call
  end

  success = true
ensure
  logger.info "Finished warmup work #{success ? 'successfully' : 'with error'}"
end
safely_spawn_thread(&block) click to toggle source
# File lib/warm_blanket/orchestrator.rb, line 78
def safely_spawn_thread(&block)
  Thread.new do
    begin
      block.call
    rescue => e
      logger.error "Caught error that caused background thread to die #{e.class}: #{e.message}"
      logger.debug "#{e.backtrace.join("\n")}"
    end
  end
end
spawn_warmup_threads() click to toggle source
# File lib/warm_blanket/orchestrator.rb, line 99
def spawn_warmup_threads
  # Create remaining threads
  (warmup_threads - 1).times do
    safely_spawn_thread do
      perform_warmup_requests
    end
  end

  # Reuse current thread
  perform_warmup_requests
end
wait_for_port_to_open() click to toggle source
# File lib/warm_blanket/orchestrator.rb, line 95
def wait_for_port_to_open
  wait_for_port_factory.new(port: port, time_deadline: warmup_deadline).call
end