Class: Mongo::Socket

Inherits:
Object
  • Object
show all
Includes:
Socket::Constants
Defined in:
lib/mongo/socket.rb,
lib/mongo/socket/ssl.rb,
lib/mongo/socket/tcp.rb,
lib/mongo/socket/unix.rb

Overview

Provides additional data around sockets for the driver’s use.

Since:

  • 2.0.0

Direct Known Subclasses

SSL, TCP, Unix

Defined Under Namespace

Classes: SSL, TCP, Unix

Constant Summary collapse

SSL_ERROR =

Error message for SSL related exceptions.

Since:

  • 2.0.0

'MongoDB may not be configured with SSL support'.freeze
TIMEOUT_ERROR =
Deprecated.

Error message for timeouts on socket calls.

Since:

  • 2.0.0

'Socket request timed out'.freeze
TIMEOUT_PACK =

The pack directive for timeouts.

Since:

  • 2.0.0

'l_2'.freeze
WRITE_CHUNK_SIZE =

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

Write data to the socket in chunks of this size.

Since:

  • 2.0.0

65536

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#familyInteger (readonly)

Returns family The type of host family.

Returns:

  • (Integer)

    family The type of host family.

Since:

  • 2.0.0



49
50
51
# File 'lib/mongo/socket.rb', line 49

def family
  @family
end

#optionsHash (readonly)

Returns The options.

Returns:

  • (Hash)

    The options.

Since:

  • 2.0.0



55
56
57
# File 'lib/mongo/socket.rb', line 55

def options
  @options
end

#socketSocket (readonly)

Returns socket The wrapped socket.

Returns:

  • (Socket)

    socket The wrapped socket.

Since:

  • 2.0.0



52
53
54
# File 'lib/mongo/socket.rb', line 52

def socket
  @socket
end

#timeoutFloat (readonly)

Returns timeout The socket timeout.

Returns:

  • (Float)

    timeout The socket timeout.

Since:

  • 2.0.0



58
59
60
# File 'lib/mongo/socket.rb', line 58

def timeout
  @timeout
end

Instance Method Details

#alive?true, false

Deprecated.

Use #connectable? on the connection instead.

Is the socket connection alive?

Examples:

Is the socket alive?

socket.alive?

Returns:

  • (true, false)

    If the socket is alive.

Since:

  • 2.0.0



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/mongo/socket.rb', line 68

def alive?
  sock_arr = [ @socket ]
  if Kernel::select(sock_arr, nil, sock_arr, 0)
    # The eof? call is supposed to return immediately since select
    # indicated the socket is readable. However, if @socket is an SSL
    # socket, eof? can block anyway - see RUBY-2140.
    begin
      Timeout.timeout(0.1) do
        eof?
      end
    rescue ::Timeout::Error
      true
    end
  else
    true
  end
end

#closetrue

Close the socket.

Examples:

Close the socket.

socket.close

Returns:

  • (true)

    Always true.

Since:

  • 2.0.0



94
95
96
97
# File 'lib/mongo/socket.rb', line 94

def close
  @socket.close rescue nil
  true
end

#connectable?true

Deprecated.

For backwards compatibilty only, do not use.

Returns:

  • (true)

    Always true.

Since:

  • 2.0.0



205
206
207
# File 'lib/mongo/socket.rb', line 205

def connectable?
  true
end

#eof?Boolean

Tests if this socket has reached EOF. Primarily used for liveness checks.

Returns:

  • (Boolean)

Since:

  • 2.0.5



194
195
196
197
198
# File 'lib/mongo/socket.rb', line 194

def eof?
  @socket.eof?
rescue IOError, SystemCallError
  true
end

#gets(*args) ⇒ Object

Delegates gets to the underlying socket.

Examples:

Get the next line.

socket.gets(10)

Parameters:

  • args (Array<Object>)

    The arguments to pass through.

Returns:

  • (Object)

    The returned bytes.

Since:

  • 2.0.0



109
110
111
# File 'lib/mongo/socket.rb', line 109

def gets(*args)
  handle_errors { @socket.gets(*args) }
end

#read(length) ⇒ Object

Will read all data from the socket for the provided number of bytes. If no data is returned, an exception will be raised.

Examples:

Read all the requested data from the socket.

socket.read(4096)

Parameters:

  • length (Integer)

    The number of bytes to read.

Returns:

  • (Object)

    The data from the socket.

Raises:

  • (Mongo::SocketError)

    If not all data is returned.

Since:

  • 2.0.0



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/mongo/socket.rb', line 126

def read(length)
  handle_errors do
    data = read_from_socket(length)
    unless (data.length > 0 || length == 0)
      raise IOError, "Expected to read > 0 bytes but read 0 bytes"
    end
    while data.length < length
      chunk = read_from_socket(length - data.length)
      unless (chunk.length > 0 || length == 0)
        raise IOError, "Expected to read > 0 bytes but read 0 bytes"
      end
      data << chunk
    end
    data
  end
end

#readbyteObject

Read a single byte from the socket.

Examples:

Read a single byte.

socket.readbyte

Returns:

  • (Object)

    The read byte.

Since:

  • 2.0.0



151
152
153
# File 'lib/mongo/socket.rb', line 151

def readbyte
  handle_errors { @socket.readbyte }
end

#write(*args) ⇒ Integer

Writes data to the socket instance.

Examples:

Write to the socket.

socket.write(data)

Parameters:

  • args (Array<Object>)

    The data to be written.

Returns:

  • (Integer)

    The length of bytes written to the socket.

Since:

  • 2.0.0



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/mongo/socket.rb', line 165

def write(*args)
  handle_errors do
    # This method used to forward arguments to @socket.write in a
    # single call like so:
    #
    # @socket.write(*args)
    #
    # Turns out, when each buffer to be written is large (e.g. 32 MiB),
    # this write call would take an extremely long time (20+ seconds)
    # while using 100% CPU. Splitting the writes into chunks produced
    # massively better performance (0.05 seconds to write the 32 MiB of
    # data on the same hardware). Unfortunately splitting the data,
    # one would assume, results in it being copied, but this seems to be
    # a much more minor issue compared to CPU cost of writing large buffers.
    args.each do |buf|
      buf = buf.to_s
      i = 0
      while i < buf.length
        chunk = buf[i...i+WRITE_CHUNK_SIZE]
        @socket.write(chunk)
        i += WRITE_CHUNK_SIZE
      end
    end
  end
end