Class: Mongo::Socket::TCP Private

Inherits:
Mongo::Socket show all
Defined in:
lib/mongo/socket/tcp.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Wrapper for TCP sockets.

Since:

  • 2.0.0

Constant Summary

Constants inherited from Mongo::Socket

SSL_ERROR, TIMEOUT_ERROR, TIMEOUT_PACK, WRITE_CHUNK_SIZE

Instance Attribute Summary collapse

Attributes inherited from Mongo::Socket

#family, #options, #socket, #timeout

Instance Method Summary collapse

Methods inherited from Mongo::Socket

#alive?, #close, #connectable?, #connection_address, #connection_generation, #eof?, #gets, #monitor?, #read, #readbyte, #summary, #write

Constructor Details

#initialize(host, port, timeout, family, options = {}) ⇒ TCP

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initializes a new TCP socket.

Examples:

Create the TCP socket.

TCP.new('::1', 27017, 30, Socket::PF_INET)
TCP.new('127.0.0.1', 27017, 30, Socket::PF_INET)

Parameters:

  • host (String)

    The hostname or IP address.

  • port (Integer)

    The port number.

  • timeout (Float)

    The socket timeout value.

  • family (Integer)

    The socket family.

  • options (Hash) (defaults to: {})

    The options.

Options Hash (options):

  • :connect_timeout (Float)

    Connect timeout.

  • :connection_address (Address)

    Address of the connection that created this socket.

  • :connection_generation (Integer)

    Generation of the connection (for non-monitoring connections) that created this socket.

  • :monitor (true | false)

    Whether this socket was created by a monitoring connection.

Since:

  • 2.0.0



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/mongo/socket/tcp.rb', line 48

def initialize(host, port, timeout, family, options = {})
  if family.nil?
    raise ArgumentError, 'family must be specified'
  end
  super(timeout, options)
  @host, @port = host, port
  @family = family
  @socket = ::Socket.new(family, SOCK_STREAM, 0)
  begin
    set_socket_options(@socket)
    connect!
  rescue
    @socket.close
    raise
  end
end

Instance Attribute Details

#hostString (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns host The host to connect to.

Returns:

  • (String)

    host The host to connect to.

Since:

  • 2.0.0



66
67
68
# File 'lib/mongo/socket/tcp.rb', line 66

def host
  @host
end

#portInteger (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns port The port to connect to.

Returns:

  • (Integer)

    port The port to connect to.

Since:

  • 2.0.0



69
70
71
# File 'lib/mongo/socket/tcp.rb', line 69

def port
  @port
end

Instance Method Details

#connect!TCP

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

This method mutates the object by setting the socket internally.

Establishes a socket connection.

Examples:

Connect the socket.

sock.connect!

Returns:

  • (TCP)

    The connected socket instance.

Since:

  • 2.0.0



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/mongo/socket/tcp.rb', line 83

def connect!
  socket.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
  sockaddr = ::Socket.pack_sockaddr_in(port, host)
  connect_timeout = options[:connect_timeout]
  map_exceptions do
    if connect_timeout && connect_timeout != 0
      connect_with_timeout(sockaddr, connect_timeout)
    else
      connect_without_timeout(sockaddr)
    end
  end
  self
end

#connect_with_timeout(sockaddr, connect_timeout) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 2.0.0



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/mongo/socket/tcp.rb', line 103

def connect_with_timeout(sockaddr, connect_timeout)
  if connect_timeout <= 0
    raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
  end

  deadline = Utils.monotonic_time + connect_timeout
  begin
    socket.connect_nonblock(sockaddr)
  rescue IO::WaitWritable
    select_timeout = deadline - Utils.monotonic_time
    if select_timeout <= 0
      raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
    end
    if IO.select(nil, [socket], nil, select_timeout)
      retry
    else
      socket.close
      raise Error::SocketTimeoutError, "The socket took over #{connect_timeout} seconds to connect"
    end
  rescue Errno::EISCONN
    # Socket is connected, nothing more to do
  end
end

#connect_without_timeout(sockaddr) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Since:

  • 2.0.0



98
99
100
# File 'lib/mongo/socket/tcp.rb', line 98

def connect_without_timeout(sockaddr)
  socket.connect(sockaddr)
end