class ServerEngine::MultiWorkerServer

Public Class Methods

new(worker_module, load_config_proc={}, &block) click to toggle source
Calls superclass method
# File lib/serverengine/multi_worker_server.rb, line 23
def initialize(worker_module, load_config_proc={}, &block)
  @monitors = []
  @last_start_worker_time = 0

  super(worker_module, load_config_proc, &block)

  @stop_immediately_at_unrecoverable_exit = @config.fetch(:stop_immediately_at_unrecoverable_exit, false)
end

Public Instance Methods

join_workers() click to toggle source
# File lib/serverengine/multi_worker_server.rb, line 75
def join_workers
  @monitors.each {|m|
    m.join if m
  }
end
reload() click to toggle source
Calls superclass method
# File lib/serverengine/multi_worker_server.rb, line 48
def reload
  super
  @monitors.each_with_index do |m|
    m.send_reload if m
  end
  nil
end
restart(stop_graceful) click to toggle source
Calls superclass method
# File lib/serverengine/multi_worker_server.rb, line 40
def restart(stop_graceful)
  super
  @monitors.each do |m|
    m.send_stop(stop_graceful) if m
  end
  nil
end
run() click to toggle source
# File lib/serverengine/multi_worker_server.rb, line 56
def run
  while true
    num_alive = keepalive_workers
    break if num_alive == 0
    wait_tick
  end
end
scale_workers(n) click to toggle source
# File lib/serverengine/multi_worker_server.rb, line 64
def scale_workers(n)
  @num_workers = n

  plus = n - @monitors.size
  if plus > 0
    @monitors.concat Array.new(plus, nil)
  end

  nil
end
stop(stop_graceful) click to toggle source
Calls superclass method
# File lib/serverengine/multi_worker_server.rb, line 32
def stop(stop_graceful)
  super
  @monitors.each do |m|
    m.send_stop(stop_graceful) if m
  end
  nil
end

Private Instance Methods

delayed_start_worker(wid) click to toggle source
# File lib/serverengine/multi_worker_server.rb, line 132
def delayed_start_worker(wid)
  if @start_worker_delay > 0
    delay = @start_worker_delay +
      Kernel.rand * @start_worker_delay * @start_worker_delay_rand -
      @start_worker_delay * @start_worker_delay_rand / 2

    now = Time.now.to_f

    wait = delay - (now - @last_start_worker_time)
    sleep wait if wait > 0

    @last_start_worker_time = now
  end

  start_worker(wid)
end
keepalive_workers() click to toggle source
# File lib/serverengine/multi_worker_server.rb, line 98
def keepalive_workers
  num_alive = 0

  @monitors.each_with_index do |m,wid|
    if m && m.alive?
      # alive
      num_alive += 1

    elsif m && m.respond_to?(:recoverable?) && !m.recoverable?
      # exited, with unrecoverable exit code
      if @stop_immediately_at_unrecoverable_exit
        stop(true) # graceful stop for workers
        # @stop is set by Server#stop
      end
      # server will stop when all workers exited in this state
      # the last status will be used for server/supervisor/daemon
      @stop_status = m.exitstatus if m.exitstatus

    elsif wid < @num_workers
      # scale up or reboot
      unless @stop
        @monitors[wid] = delayed_start_worker(wid)
        num_alive += 1
      end

    elsif m
      # scale down
      @monitors[wid] = nil
    end
  end

  return num_alive
end
reload_config() click to toggle source
Calls superclass method
# File lib/serverengine/multi_worker_server.rb, line 83
def reload_config
  super

  @start_worker_delay = @config[:start_worker_delay] || 0
  @start_worker_delay_rand = @config[:start_worker_delay_rand] || 0.2

  scale_workers(@config[:workers] || 1)

  nil
end
wait_tick() click to toggle source
# File lib/serverengine/multi_worker_server.rb, line 94
def wait_tick
  sleep 0.5
end