class Mongo::Server::Connection

This class models the socket connections for servers and their behavior.

@since 2.0.0

Constants

PING

The ping command.

@since 2.1.0

PING_BYTES

The ping message as raw bytes.

@since 2.1.0

PING_MESSAGE

Ping message.

@since 2.1.0

Public Class Methods

new(server, options = {}) click to toggle source

Initialize a new socket connection from the client to the server.

@api private

@example Create the connection.

Connection.new(server)

@note Connection must never be directly instantiated outside of a

Server.

@param [ Mongo::Server ] server The server the connection is for. @param [ Hash ] options The connection options.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 125
def initialize(server, options = {})
  @address = server.address
  @monitoring = server.monitoring
  @options = options.freeze
  @server = server
  @ssl_options = options.reject { |k, v| !k.to_s.start_with?(SSL) }
  @socket = nil
  @pid = Process.pid
end

Public Instance Methods

connect!() click to toggle source

Tell the underlying socket to establish a connection to the host.

@example Connect to the host.

connection.connect!

@note This method mutates the connection class by setting a socket if

one previously did not exist.

@return [ true ] If the connection succeeded.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 58
def connect!
  unless socket
    @socket = address.socket(timeout, ssl_options)
    socket.connect!
    authenticate!
  end
  true
end
disconnect!() click to toggle source

Disconnect the connection.

@example Disconnect from the host.

connection.disconnect!

@note This method mutates the connection by setting the socket to nil

if the closing succeeded.

@return [ true ] If the disconnect succeeded.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 78
def disconnect!
  if socket
    socket.close
    @socket = nil
  end
  true
end
dispatch(messages, operation_id = nil) click to toggle source

Dispatch the provided messages to the connection. If the last message requires a response a reply will be returned.

@example Dispatch the messages.

connection.dispatch([ insert, command ])

@note This method is named dispatch since 'send' is a core Ruby method on

all objects.

@param [ Array<Message> ] messages The messages to dispatch. @param [ Integer ] operation_id The operation id to link messages.

@return [ Protocol::Reply ] The reply if needed.

@since 2.0.0

# File lib/mongo/server/connection.rb, line 101
def dispatch(messages, operation_id = nil)
  if monitoring.subscribers?(Monitoring::COMMAND)
    publish_command(messages, operation_id || Monitoring.next_operation_id) do |msgs|
      deliver(msgs)
    end
  else
    deliver(messages)
  end
end
ping() click to toggle source

Ping the connection to see if the server is responding to commands. This is non-blocking on the server side.

@example Ping the connection.

connection.ping

@note This uses a pre-serialized ping message for optimization.

@return [ true, false ] If the server is accepting connections.

@since 2.1.0

# File lib/mongo/server/connection.rb, line 146
def ping
  ensure_connected do |socket|
    socket.write(PING_BYTES)
    reply = Protocol::Reply.deserialize(socket, max_message_size)
    reply.documents[0][Operation::Result::OK] == 1
  end
end

Private Instance Methods

authenticate!() click to toggle source
# File lib/mongo/server/connection.rb, line 161
def authenticate!
  if options[:user]
    default_mechanism = @server.features.scram_sha_1_enabled? ? :scram : :mongodb_cr
    user = Auth::User.new(Options::Redacted.new(:auth_mech => default_mechanism).merge(options))
    Auth.get(user).login(self)
  end
end
deliver(messages) click to toggle source
# File lib/mongo/server/connection.rb, line 156
def deliver(messages)
  write(messages)
  messages.last.replyable? ? read : nil
end
write(messages, buffer = BSON::ByteBuffer.new) click to toggle source
# File lib/mongo/server/connection.rb, line 169
def write(messages, buffer = BSON::ByteBuffer.new)
  start_size = 0
  messages.each do |message|
    message.serialize(buffer, max_bson_object_size)
    if max_message_size &&
      (buffer.length - start_size) > max_message_size
      raise Error::MaxMessageSize.new(max_message_size)
      start_size = buffer.length
    end
  end
  ensure_connected{ |socket| socket.write(buffer.to_s) }
end