class Mongo::Socket
Provides additional data around sockets for the driver's use.
@since 2.0.0
Constants
Attributes
@return [ Integer ] family The type of host family.
@return [ Socket ] socket The wrapped socket.
Public Class Methods
Create the new socket for the provided family - ipv4, piv6, or unix.
@example Create a new ipv4 socket.
Socket.new(Socket::PF_INET)
@param [ Integer ] family The socket domain.
@since 2.0.0
# File lib/mongo/socket.rb, line 102 def initialize(family) @family = family @socket = ::Socket.new(family, SOCK_STREAM, 0) set_socket_options(@socket) end
Public Instance Methods
Is the socket connection alive?
@example Is the socket alive?
socket.alive?
@return [ true, false ] If the socket is alive.
@deprecated Use connectable? on the connection instead.
# File lib/mongo/socket.rb, line 58 def alive? sock_arr = [ @socket ] if Kernel::select(sock_arr, nil, sock_arr, 0) eof? else true end end
Close the socket.
@example Close the socket.
socket.close
@return [ true ] Always true.
@since 2.0.0
# File lib/mongo/socket.rb, line 75 def close @socket.close rescue true true end
Tests if this socket has reached EOF. Primarily used for liveness checks.
@since 2.0.5
# File lib/mongo/socket.rb, line 163 def eof? @socket.eof? rescue IOError, SystemCallError => _ true end
Delegates gets to the underlying socket.
@example Get the next line.
socket.gets(10)
@param [ Array<Object> ] args The arguments to pass through.
@return [ Object ] The returned bytes.
@since 2.0.0
# File lib/mongo/socket.rb, line 90 def gets(*args) handle_errors { @socket.gets(*args) } end
Will read all data from the socket for the provided number of bytes. If no data is returned, an exception will be raised.
@example Read all the requested data from the socket.
socket.read(4096)
@param [ Integer ] length The number of bytes to read.
@raise [ Mongo::SocketError ] If not all data is returned.
@return [ Object ] The data from the socket.
@since 2.0.0
# File lib/mongo/socket.rb, line 121 def read(length) handle_errors do data = read_from_socket(length) raise IOError unless (data.length > 0 || length == 0) while data.length < length chunk = read_from_socket(length - data.length) raise IOError unless (chunk.length > 0 || length == 0) data << chunk end data end end
Read a single byte from the socket.
@example Read a single byte.
socket.readbyte
@return [ Object ] The read byte.
@since 2.0.0
# File lib/mongo/socket.rb, line 142 def readbyte handle_errors { @socket.readbyte } end
Writes data to the socket instance.
@example Write to the socket.
socket.write(data)
@param [ Array<Object> ] args The data to be written.
@return [ Integer ] The length of bytes written to the socket.
@since 2.0.0
# File lib/mongo/socket.rb, line 156 def write(*args) handle_errors { @socket.write(*args) } end
Private Instance Methods
# File lib/mongo/socket.rb, line 197 def handle_errors begin yield rescue Errno::ETIMEDOUT raise Error::SocketTimeoutError, TIMEOUT_ERROR rescue IOError, SystemCallError => e raise Error::SocketError, e.message rescue OpenSSL::SSL::SSLError raise Error::SocketError, SSL_ERROR end end
# File lib/mongo/socket.rb, line 171 def read_from_socket(length) data = String.new deadline = (Time.now + timeout) if timeout begin while (data.length < length) data << @socket.read_nonblock(length - data.length) end rescue IO::WaitReadable select_timeout = (deadline - Time.now) if deadline if (select_timeout && select_timeout <= 0) || !Kernel::select([@socket], nil, [@socket], select_timeout) raise Timeout::Error.new("Took more than #{timeout} seconds to receive data.") end retry end data end
# File lib/mongo/socket.rb, line 193 def set_socket_options(sock) sock.set_encoding(BSON::BINARY) end
# File lib/mongo/socket.rb, line 189 def unix_socket?(sock) defined?(UNIXSocket) && sock.is_a?(UNIXSocket) end