class Flapjack::CLI::Flapper

Public Class Methods

new(global_options, options) click to toggle source
# File lib/flapjack/cli/flapper.rb, line 9
def initialize(global_options, options)
  @global_options = global_options
  @options = options

  if @global_options[:'force-utf8']
    Encoding.default_external = 'UTF-8'
    Encoding.default_internal = 'UTF-8'
  end

  @config = Flapjack::Configuration.new
  @config.load(global_options[:config])
  @config_env = @config.all

  if @config_env.nil? || @config_env.empty?
    exit_now! "No config data found in '#{global_options[:config]}'"
  end
end

Private Class Methods

local_ip() click to toggle source
# File lib/flapjack/cli/flapper.rb, line 42
def self.local_ip
  # turn off reverse DNS resolution temporarily
  orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true

  begin
    UDPSocket.open do |s|
      s.connect '64.233.187.99', 1
      s.addr.last
    end
  rescue Errno::ENETUNREACH => e
    '127.0.0.1'
  end
ensure
  Socket.do_not_reverse_lookup = orig
end

Public Instance Methods

start() click to toggle source
# File lib/flapjack/cli/flapper.rb, line 27
def start
  puts "flapper starting..."
  main(@options['bind-ip'] || Flapjack::CLI::Flapper.local_ip, @options['bind-port'].to_i, @options[:frequency])
  puts " done."
end

Private Instance Methods

get_pid() click to toggle source
# File lib/flapjack/cli/flapper.rb, line 139
def get_pid
  IO.read(@pidfile).chomp.to_i
rescue StandardError
  pid = nil
end
main(bind_ip, bind_port, frequency) click to toggle source
# File lib/flapjack/cli/flapper.rb, line 58
def main(bind_ip, bind_port, frequency)
  raise "bind_port must be an integer" unless bind_port.is_a?(Integer)
  start_every = frequency
  stop_after = frequency.to_f / 2

  begin
    loop do
      begin
        fds = []
        Timeout::timeout(stop_after) do
          puts "#{Time.now}: starting server"

          acceptor = TCPServer.open(bind_ip, bind_port)
          fds = [acceptor]

          while true
            if ios = select(fds, [], [], 10)
              reads = ios.first
              reads.each do |client|
                if client == acceptor
                  puts 'Someone connected to server. Adding socket to fds.'
                  client, sockaddr = acceptor.accept
                  fds << client
                elsif client.eof?
                  puts "Client disconnected"
                  fds.delete(client)
                  client.close
                else
                  # Perform a blocking-read until new-line is encountered.
                  # We know the client is writing, so as long as it adheres to the
                  # new-line protocol, we shouldn't block for very long.
                  data = client.gets("\n")
                  if data =~ /quit/i
                    fds.delete(client)
                    client.close
                  end
                end
              end
            end
          end
        end
      rescue Timeout::Error
        puts "#{Time.now}: stopping server"
      ensure
        # should trigger even for an Interrupt
        puts "Cleaning up"
        fds.each {|c| c.close}
      end

      sleep_for = start_every - stop_after
      puts "sleeping for #{sleep_for}"
      sleep(sleep_for)
    end
  rescue Interrupt
    puts "interrupted"
  end
end
process_exists(pid) click to toggle source
# File lib/flapjack/cli/flapper.rb, line 116
def process_exists(pid)
  return unless pid
  begin
    Process.kill(0, pid)
    return true
  rescue Errno::ESRCH
    return false
  end
end
wait_pid_gone(pid, timeout = 30) click to toggle source

wait until the specified pid no longer exists, or until a timeout is reached

# File lib/flapjack/cli/flapper.rb, line 127
def wait_pid_gone(pid, timeout = 30)
  print "waiting for a max of #{timeout} seconds for process #{pid} to exit" if process_exists(pid)
  started_at = Time.now.to_i
  while process_exists(pid)
    break unless (Time.now.to_i - started_at < timeout)
    print '.'
    sleep 1
  end
  puts ''
  !process_exists(pid)
end