class ZTK::TCPSocketCheck

TCP Socket Checking Class

This class has two basic modes of operation:

By default we will perform a read test against the host and port specified. In this mode we will attempt to connect to the host and port supplied and if we can read any amount of data, regardless of the content we view this as success.

If data is supplied via the configuration, this will change the mode of operation to a write test. Certain services, such as HTTP don't send any data unless you send something first. In this mode we will attempt to connect to the host and port supplied, once connected we will write the supplied data to the socket and then attempt to read from the socket. If we can read any amount of data, reagardless of the conent we view this as success.

Typical usage:

Given a host and port we want to check, we can do something like this:

sc = ZTK::TCPSocketCheck.new(:host => "www.github.com", :port => 22)

Then if we want to check if this host is responding on the specified port:

sc.ready? and puts("They are there!")

This works well for protocols that spew forth some data right away for use to read. However, with certain protocols, such as HTTP, we need to send some data first before we get a response.

Given we want to check a host and port that requires some giving before we can take:

sc = ZTK::TCPSocketCheck.new(:host => "www.google.com", :port => 80, :data => "GET")

Then if we want to check if this host is responding on the specified port:

sc.ready? and puts("They are there!")

The ready? methods timeout is bound to the configuration option timeout.

If we are waiting for a service to come online, we can do this:

sc.wait and puts("They are there!")

The wait methods timeout is bound to the configuration option wait.

@author Zachary Patten <zpatten AT jovelabs DOT io>

Public Class Methods

new(configuration={}) click to toggle source

@param [Hash] configuration Configuration options hash. @option config [String] :host Host to connect to. @option config [Integer, String] :port Port to connect to. @option config [String] :data Data to send to host to provoke a response. @option config [Integer] :timeout (5) Set the IO select timeout. @option config [Integer] :wait (60) Set the amount of time before the wait

method call will timeout.
Calls superclass method ZTK::Base::new
# File lib/ztk/tcp_socket_check.rb, line 73
def initialize(configuration={})
  super({
    :timeout => 5,
    :wait => 60
  }, configuration)
end

Public Instance Methods

ready?() click to toggle source

Check to see if socket on the host and port specified is ready. This method will timeout and return false after the amount of seconds specified in config.timeout has passed if the socket has not become ready.

@return [Boolean] Returns true or false depending on Whether the socket

is ready or not.
# File lib/ztk/tcp_socket_check.rb, line 86
def ready?
  config.host.nil? and log_and_raise(TCPSocketCheckError, "You must supply a host!")
  config.port.nil? and log_and_raise(TCPSocketCheckError, "You must supply a port!")

  socket = TCPSocket.new(config.host, config.port)

  if config.data.nil?
    config.ui.logger.debug { "read(#{config.host}:#{config.port})" }
    ((IO.select([socket], nil, nil, config.timeout) && socket.gets) ? true : false)
  else
    config.ui.logger.debug { "write(#{config.host}:#{config.port}, #{config.data.size} bytes)" }
    ((IO.select(nil, [socket], nil, config.timeout) && socket.write(config.data)) ? true : false)
  end

rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::EHOSTUNREACH, Errno::EHOSTDOWN, Errno::ENETUNREACH => e
  config.ui.logger.debug { "#{config.host}:#{config.port} - #{e.message}" }
  false
ensure
  (socket && socket.close)
end
wait() click to toggle source

Wait for the socket on the host and port specified to become ready. This method will timeout and return false after the amount of seconds specified in config.wait has passed if the socket has not become ready.

@return [Boolean] Returns true or false depending on Whether the socket

became ready or not.
# File lib/ztk/tcp_socket_check.rb, line 113
def wait
  config.ui.logger.debug { "Waiting for socket to become available; timeout after #{config.wait} seconds." }
  Timeout.timeout(config.wait) do
    until ready?
      config.ui.logger.debug { "Sleeping 1 second." }
      sleep(1)
    end
  end
  true
rescue Timeout::Error => e
  config.ui.logger.warn { "socket(#{config.host}:#{config.port}) timeout!" }
  false
end