Class: Mongo::Server::Connection

Inherits:
ConnectionBase show all
Extended by:
Forwardable
Includes:
Id, Monitoring::Publishable, Retryable
Defined in:
lib/mongo/server/connection.rb

Overview

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

Since:

  • 2.0.0

Constant Summary collapse

PING =
Deprecated.

No longer necessary with Server Selection specification.

The ping command.

Since:

  • 2.1.0

{ ping: 1 }.freeze
PING_OP_MSG =
Deprecated.

No longer necessary with Server Selection specification.

The ping command for an OP_MSG

Since:

  • 2.5.0

{ :ping => 1, '$db' => Database::ADMIN }.freeze
PING_OP_MSG_MESSAGE =
Deprecated.

No longer necessary with Server Selection specification.

Ping message as an OP_MSG

Since:

  • 2.5.0

Protocol::Msg.new([], {}, PING_OP_MSG)
PING_OP_MSG_BYTES =
Deprecated.

No longer necessary with Server Selection specification.

The ping OP_MSG message as raw bytes

Since:

  • 2.5.0

PING_OP_MSG_MESSAGE.serialize.to_s.freeze

Constants included from Loggable

Loggable::PREFIX

Constants inherited from ConnectionBase

Mongo::Server::ConnectionBase::DEFAULT_MAX_BSON_OBJECT_SIZE, Mongo::Server::ConnectionBase::MAX_BSON_COMMAND_OVERHEAD, Mongo::Server::ConnectionBase::REDUCED_MAX_BSON_SIZE

Instance Attribute Summary collapse

Attributes included from Monitoring::Publishable

#monitoring

Attributes inherited from ConnectionBase

#description, #options, #server

Attributes inherited from ConnectionCommon

#compressor, #pid

Instance Method Summary collapse

Methods included from Id

included

Methods included from Retryable

#read_worker, #select_server, #with_overload_retry, #write_worker

Methods included from Monitoring::Publishable

#publish_cmap_event, #publish_event, #publish_sdam_event

Methods included from Loggable

#log_debug, #log_error, #log_fatal, #log_info, #log_warn, #logger

Methods inherited from ConnectionBase

#app_metadata, #dispatch, #generation, #service_id

Methods inherited from ConnectionCommon

#handshake_command, #handshake_document, #interrupt_socket

Constructor Details

#initialize(server, options = {}) ⇒ Connection

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:

Connection must never be directly instantiated outside of a Server.

Creates a new connection object to the specified target address with the specified options.

The constructor does not perform any I/O (and thus does not create sockets, handshakes nor authenticates); call connect! method on the connection object to create the network connection.

Examples:

Create the connection.

Connection.new(server)

Parameters:

  • server (Mongo::Server)

    The server the connection is for.

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

    The connection options.

Options Hash (options):

  • :pipe (IO)

    The file descriptor for the read end of the pipe to listen on during the select system call when reading from the socket.

  • :generation (Integer)

    The generation of this connection. The generation should only be specified in this option when not in load-balancing mode, and it should be the generation of the connection pool when the connection is created. In load-balancing mode, the generation is set on the connection after the handshake completes.

  • :server_api (Hash)

    The requested server API version. This hash can have the following items:

    • :version -- string
    • :strict -- boolean
    • :deprecation_errors -- boolean

Since:

  • 2.0.0



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/mongo/server/connection.rb', line 90

def initialize(server, options = {})
  super()
  if server.load_balancer? && options[:generation]
    raise ArgumentError, 'Generation cannot be set when server is a load balancer'
  end

  @id = server.next_connection_id
  @global_id = self.class.next_id
  @monitoring = server.monitoring
  @options = options.freeze
  @server = server
  @socket = nil
  @last_checkin = nil
  @auth_mechanism = nil
  @pid = Process.pid
  @pin_reasons = Set.new

  publish_cmap_event(
    Monitoring::Event::Cmap::ConnectionCreated.new(address, id)
  )
end

Instance Attribute Details

#global_idInteger (readonly)

across all connections.

Returns:

  • (Integer)

    The global ID for the connection. This will be unique

Since:

  • 2.0.0



125
126
127
# File 'lib/mongo/server/connection.rb', line 125

def global_id
  @global_id
end

#idInteger (readonly)

across connections to the same server object.

Returns:

  • (Integer)

    The ID for the connection. This will be unique

Since:

  • 2.9.0



121
122
123
# File 'lib/mongo/server/connection.rb', line 121

def id
  @id
end

#last_checkinTime (readonly)

Returns The last time the connection was checked back into a pool.

Returns:

  • (Time)

    The last time the connection was checked back into a pool.

Since:

  • 2.5.0



115
116
117
# File 'lib/mongo/server/connection.rb', line 115

def last_checkin
  @last_checkin
end

Instance Method Details

#closed?true | false

Whether the connection was closed.

Closed connections should no longer be used. Instead obtain a new connection from the connection pool.

Returns:

  • (true | false)

    Whether connection was closed.

Since:

  • 2.9.0



153
154
155
# File 'lib/mongo/server/connection.rb', line 153

def closed?
  !!@closed
end

#connect!(context = nil) ⇒ true

Note:

This method mutates the connection object by setting a socket if one previously did not exist.

Establishes a network connection to the target address.

If the connection is already established, this method does nothing.

Examples:

Connect to the host.

connection.connect!

Returns:

  • (true)

    If the connection succeeded.

Since:

  • 2.0.0



229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/mongo/server/connection.rb', line 229

def connect!(context = nil)
  raise_if_closed!

  unless @socket
    @socket = create_socket(context)
    @description, @compressor = do_connect

    if server.load_balancer?
      if Lint.enabled? && !service_id
        raise Error::InternalDriverError,
              'The connection is to a load balancer and it must have service_id set here, but does not'
      end
      @generation = connection_pool.generation_manager.generation(service_id: service_id)
    end

    publish_cmap_event(
      Monitoring::Event::Cmap::ConnectionReady.new(address, id)
    )

    @close_event_published = false
  end
  true
end

#connected?true | false

Whether the connection was connected and was not interrupted, closed, or had an error raised.

Returns:

  • (true | false)

    if the connection was connected.

Since:

  • 2.0.0



141
142
143
# File 'lib/mongo/server/connection.rb', line 141

def connected?
  !closed? && !error? && !interrupted? && !!@socket
end

#connection_poolObject

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.

The connection pool from which this connection was created. May be nil.

Since:

  • 2.0.0



133
134
135
# File 'lib/mongo/server/connection.rb', line 133

def connection_pool
  options[:connection_pool]
end

#disconnect!(options = nil) ⇒ true

Note:

Once a connection is disconnected, it should no longer be used. A new connection should be obtained from the connection pool which will either return a ready connection or create a new connection. If linting is enabled, reusing a disconnected connection will raise Error::LintError. If linting is not enabled, a warning will be logged.

Note:

This method mutates the connection object by setting the socket to nil if the closing succeeded.

Disconnect the connection.

Parameters:

  • options (Hash) (defaults to: nil)

    a customizable set of options

Options Hash (options):

  • :reason (Symbol)

    The reason why the connection is being closed.

  • :interrupted (true | false)

    Whether or not the connection was interrupted.

Returns:

  • (true)

    If the disconnect succeeded.

Since:

  • 2.0.0



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
# File 'lib/mongo/server/connection.rb', line 311

def disconnect!(options = nil)
  # NOTE: @closed may be true here but we also may have a socket.
  # Check the socket and not @closed flag.
  @auth_mechanism = nil
  @last_checkin = nil
  if socket
    begin
      socket.close
    rescue StandardError
      nil
    end
    @socket = nil
  end
  @closed = true
  interrupted! if options && options[:interrupted]

  # To satisfy CMAP spec tests, publish close events even if the
  # socket was never connected (and thus the ready event was never
  # published). But track whether we published close event and do not
  # publish it multiple times, unless the socket was reconnected -
  # in that case publish the close event once per socket close.
  unless @close_event_published
    reason = options && options[:reason]
    publish_cmap_event(
      Monitoring::Event::Cmap::ConnectionClosed.new(
        address,
        id,
        reason
      )
    )
    @close_event_published = true
  end

  true
end

#error?Boolean

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:

  • (Boolean)

Since:

  • 2.0.0



173
174
175
# File 'lib/mongo/server/connection.rb', line 173

def error?
  !!@error
end

#interrupted!Object

Mark the connection as interrupted.

Since:

  • 2.0.0



168
169
170
# File 'lib/mongo/server/connection.rb', line 168

def interrupted!
  @interrupted = true
end

#interrupted?true | false

Whether the connection was interrupted.

Interrupted connections were already removed from the pool and should not be checked back into the pool.

Returns:

  • (true | false)

    Whether connection was interrupted.

Since:

  • 2.0.0



163
164
165
# File 'lib/mongo/server/connection.rb', line 163

def interrupted?
  !!@interrupted
end

#pin(reason = :cursor) ⇒ 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.

Mark the connection as pinned for the given reason.

Parameters:

  • reason (Symbol) (defaults to: :cursor)

    The reason for pinning (:cursor or :transaction). Defaults to :cursor for backward compatibility.

Since:

  • 2.0.0



195
196
197
# File 'lib/mongo/server/connection.rb', line 195

def pin(reason = :cursor)
  @pin_reasons << reason
end

#pingtrue, false

Deprecated.

No longer necessary with Server Selection specification.

Note:

This uses a pre-serialized ping message for optimization.

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

Examples:

Ping the connection.

connection.ping

Returns:

  • (true, false)

    If the server is accepting connections.

Since:

  • 2.1.0



360
361
362
363
364
365
366
367
368
# File 'lib/mongo/server/connection.rb', line 360

def ping
  ensure_connected do |socket|
    reply = add_server_diagnostics do
      socket.write(PING_OP_MSG_BYTES)
      Protocol::Message.deserialize(socket, max_message_size)
    end
    reply.documents[0][Operation::Result::OK] == 1
  end
end

#pinned?Boolean

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.

Whether the connection is used by a transaction or cursor operations.

Pinned connections should not be disconnected and removed from a connection pool if they are idle or stale.

@return [ true | false ] Whether connection is pinned.

Returns:

  • (Boolean)

Since:

  • 2.0.0



185
186
187
# File 'lib/mongo/server/connection.rb', line 185

def pinned?
  !@pin_reasons.empty?
end

#record_checkin!self

Record the last checkin time.

Examples:

Record the checkin time on this connection.

connection.record_checkin!

Returns:

  • (self)

Since:

  • 2.5.0



389
390
391
392
# File 'lib/mongo/server/connection.rb', line 389

def record_checkin!
  @last_checkin = Time.now
  self
end

#socket_timeoutFloat Also known as: timeout

Get the timeout to execute an operation on a socket.

Returns:

  • (Float)

    The operation timeout in seconds.

Since:

  • 2.0.0



375
376
377
# File 'lib/mongo/server/connection.rb', line 375

def socket_timeout
  @timeout ||= options[:socket_timeout]
end

#transportSymbol | nil

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.

Get the transport type for this connection.

Returns:

  • (Symbol | nil)

    The transport type, :tcp or :unix, or nil if no socket.

Since:

  • 2.0.0



399
400
401
402
403
404
405
406
407
408
# File 'lib/mongo/server/connection.rb', line 399

def transport
  return nil if @socket.nil?

  case @socket
  when Mongo::Socket::Unix
    :unix
  else
    :tcp
  end
end

#unpin(reason = :cursor) ⇒ 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.

Remove a pin from the connection for the given reason.

Parameters:

  • reason (Symbol) (defaults to: :cursor)

    The reason to unpin (:cursor or :transaction). Defaults to :cursor for backward compatibility.

Since:

  • 2.0.0



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

def unpin(reason = :cursor)
  @pin_reasons.delete(reason)
end

#unpin_allObject

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.

Remove all pins from the connection.

Since:

  • 2.0.0



212
213
214
# File 'lib/mongo/server/connection.rb', line 212

def unpin_all
  @pin_reasons.clear
end