Arborist::Monitor::Socket::

TCP

class
Superclass
Object
Included Modules
Arborist::Monitor::ConnectionBatching
Extended With
Loggability

Arborist TCP socket monitor logic

Constants

USED_PROPERTIES

Always request the node addresses and port.

Public Class Methods

anchor
new( timeout: Arborist::Monitor::Socket.default_timeout, batch_size: Arborist::Monitor::Socket.batch_size )

Create a new TCP monitor with the specified options. Valid options are:

:timeout

Set the number of seconds to wait for a connection for each node.

:batch_size

The number of UDP connection attempts to perform simultaneously.
# File lib/arborist/monitor/socket.rb, line 64
def initialize( timeout: Arborist::Monitor::Socket.default_timeout, batch_size: Arborist::Monitor::Socket.batch_size )
        self.timeout = timeout
        self.batch_size = batch_size
end
anchor
node_properties()

Return the properties used by this monitor.

# File lib/arborist/monitor/socket.rb, line 53
def self::node_properties
        return USED_PROPERTIES
end
anchor
run( nodes )

Instantiate a monitor check and run it for the specified nodes.

# File lib/arborist/monitor/socket.rb, line 47
def self::run( nodes )
        return self.new.run( nodes )
end

Public Instance Methods

anchor
make_connections_enum( nodes )

Return an Enumerator that lazily yields Hashes of the form expected by the ConnectionBatching mixin for each of the specified nodes.

# File lib/arborist/monitor/socket.rb, line 76
def make_connections_enum( nodes )
        return nodes.lazy.map do |identifier, node_data|
                self.log.debug "Creating a socket for %s" % [ identifier ]

                # :TODO: Should this try all the addresses? Should you be able to specify an
                # address for a Service?
                address = node_data['addresses'].first
                port = node_data['port']
                sockaddr = nil

                self.log.debug "Creating TCP connection for %s:%d" % [ address, port ]
                sock = Socket.new( :INET, :STREAM )

                conn = begin
                                sockaddr = Socket.sockaddr_in( port, address )
                                sock.connect_nonblock( sockaddr )
                                sock
                        rescue Errno::EINPROGRESS
                                self.log.debug "  connection started"
                                sock
                        rescue => err
                                self.log.error "  %p setting up connection: %s" % [ err.class, err.message ]
                                err
                        end

                { conn: conn, identifier: identifier }
        end
end
anchor
status_for_conn( conn_hash, duration )

Build a status for the specified conn_hash after its :conn has indicated it is ready.

# File lib/arborist/monitor/socket.rb, line 108
def status_for_conn( conn_hash, duration )
        sock = conn_hash[:conn]
        # Why getpeername? Testing socket success without read()ing, I think?
        # FreeBSD source?
        res = sock.getpeername
        return {
                tcp_socket_connect: { duration: duration }
        }
rescue SocketError, SystemCallError => err
        self.log.debug "Got %p while connecting to %s" % [ err.class, conn_hash[:identifier] ]
        begin
                sock.read( 1 )
        rescue => err
                return { error: err.message }
        end
ensure
        sock.close if sock
end