123456789_123456789_123456789_123456789_123456789_

Class: Mongo::Server

Overview

Represents a single server on the server side that can be standalone, part of a replica set, or a mongos.

Since:

  • 2.0.0

Constant Summary

Loggable - Included

PREFIX

Class Method Summary

Instance Attribute Summary

Event::Publisher - Included

Monitoring::Publishable - Included

Instance Method Summary

Event::Publisher - Included

#publish

Publish the provided event.

Monitoring::Publishable - Included

Loggable - Included

#log_debug

Convenience method to log debug messages with the standard prefix.

#log_error

Convenience method to log error messages with the standard prefix.

#log_fatal

Convenience method to log fatal messages with the standard prefix.

#log_info

Convenience method to log info messages with the standard prefix.

#log_warn

Convenience method to log warn messages with the standard prefix.

#logger

Get the logger instance.

#_mongo_log_prefix, #format_message

Instance Attribute Details

#addressString (readonly)

Returns:

  • (String)

    The configured address for the server.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 106

attr_reader :address

#clusterCluster (readonly)

Returns:

  • (Cluster)

    cluster The server cluster.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 109

attr_reader :cluster

#connectable?true, false (readonly)

Deprecated.

No longer necessary with Server Selection specification.

Determine if a connection to the server is able to be established and messages can be sent to it.

Examples:

Is the server connectable?

server.connectable?

Returns:

  • (true, false)

    If the server is connectable.

Since:

  • 2.1.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 261

def connectable?; end

#connected?true|false (readonly)

This method is for internal use only.

Whether the server is connected.

Returns:

  • (true|false)

    Whether the server is connected.

Since:

  • 2.7.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 320

def connected?
  @connected
end

#descriptionServer::Description (readonly)

Returns:

Since:

  • 2.0.0

[ GitHub ]

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

attr_reader :description

#force_load_balancer?true | false (readonly)

This method is for internal use only.

Returns whether this server is forced to be a load balancer.

Returns:

  • (true | false)

    Whether this server is forced to be a load balancer.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 130

def force_load_balancer?
  options[:connect] == :load_balanced
end

#monitornil | Monitor (readonly)

Returns:

  • (nil | Monitor)

    monitor The server monitor. nil if the servenr was created with monitoring_io: false option.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 113

attr_reader :monitor

#monitoringMonitoring (readonly)

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 119

attr_reader :monitoring

#optionsHash (readonly)

Returns:

  • (Hash)

    The options hash.

Since:

  • 2.0.0

[ GitHub ]

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

attr_reader :options

#retry_reads?Boolean (readonly)

This method is for internal use only.

Whether the server supports modern read retries.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 543

def retry_reads?
  !!(features.sessions_enabled? && logical_session_timeout)
end

#retry_writes?true, false (readonly)

Note:

Retryable writes are only available on server versions 3.6+ and with sharded clusters or replica sets.

Note:

Some of the conditions in this method automatically return false for for load balanced topologies. The conditions in this method should always be true, since load-balanced topologies are only available on MongoDB 5.0+, and not for standalone topologies. Therefore, we can assume that retry writes are enabled.

Will writes sent to this server be retried.

Examples:

Will writes be retried.

server.retry_writes?

Returns:

  • (true, false)

    If writes will be retried.

Since:

  • 2.5.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 564

def retry_writes?
  !!(features.sessions_enabled? && logical_session_timeout && !standalone?) || load_balancer?
end

#round_trip_time_averagerRoundTripTimeAverager (readonly)

This method is for internal use only.

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 233

attr_reader :round_trip_time_averager

#scan_semaphoreSemaphore (readonly)

This method is for internal use only.

Returns:

  • (Semaphore)

    Semaphore to signal to request an immediate scan of this server by its monitor, if one is running.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 229

attr_reader :scan_semaphore

Instance Method Details

#==(other) ⇒ true, false

Is this server equal to another?

Examples:

Is the server equal to the other?

server == other

Parameters:

  • other (Object)

    The object to compare to.

Returns:

  • (true, false)

    If the servers are equal.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 245

def ==(other)
  return false unless other.is_a?(Server)
  address == other.address
end

#clear_connection_pool(service_id: nil, interrupt_in_use_connections: false)

This method is for internal use only.

Parameters:

  • :service_id (Object)

    Close connections with the specified service id only.

  • :interrupt_in_use_connections (true | false)

    Whether or not the cleared connections should be interrupted as well.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 667

def clear_connection_pool(service_id: nil, interrupt_in_use_connections: false)
  @pool_lock.synchronize do
    # A server being marked unknown after it is closed is technically
    # incorrect but it does not meaningfully alter any state.
    # Because historically the driver permitted servers to be marked
    # unknown at any time, continue doing so even if the pool is closed.
    if @pool && !@pool.closed?
      @pool.disconnect!(service_id: service_id, interrupt_in_use_connections: interrupt_in_use_connections)
    end
  end
end

#clear_description

This method is for internal use only.

Clear the servers description so that it is considered unknown and can be safely disconnected.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 657

def clear_description
  @description = Mongo::Server::Description.new(address, {})
end

#close

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 294

def close
  if monitor
    monitor.stop!
  end

  @connected = false

  _pool = nil
  @pool_lock.synchronize do
    _pool, @pool = @pool, nil
  end

  # TODO: change this to _pool.close in RUBY-3174.
  # Clear the pool. If the server is not unknown then the
  # pool will stay ready. Stop the background populator thread.
  _pool&.close(stay_ready: true)

  nil
end

#compressorString | nil

Deprecated.
Note:

Compression is negotiated for each connection separately.

The compressor negotiated by the server monitor, if any.

This attribute is nil if no server check has not yet completed, and if no compression was negatiated.

Returns:

  • (String | nil)

    The negotiated compressor.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 181

def compressor
  if monitor
    monitor.compressor
  else
    nil
  end
end

#disconnect!true

Disconnect the driver from this server.

Disconnects all idle connections to this server in its connection pool, if any exist. Stops the populator of the connection pool, if it is running. Does not immediately close connections which are presently checked out (i.e. in use) - such connections will be closed when they are returned to their respective connection pools. Stop the server’s background monitor.

Returns:

  • (true)

    Always true.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 275

def disconnect!
  if monitor
    monitor.stop!
  end

  @connected = false

  # The current CMAP spec requires a pool to be mostly unusable
  # if its server is unknown (or, therefore, disconnected).
  # However any outstanding operations should continue to completion,
  # and their connections need to be checked into the pool to be
  # torn down. Because of this cleanup requirement we cannot just
  # close the pool and set it to nil here, to be recreated the next
  # time the server is discovered.
  pool_internal&.clear

  true
end

#handle_auth_failure!Object

Handle authentication failure.

Examples:

Handle possible authentication failure.

server.handle_auth_failure! do
  Auth.get(user).(self)
end

Returns:

  • (Object)

    The result of the block execution.

Raises:

Since:

  • 2.3.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 524

def handle_auth_failure!
  yield
rescue Mongo::Error::SocketTimeoutError
  # possibly cluster is slow, do not give up on it
  raise
rescue Mongo::Error::SocketError, Auth::Unauthorized => e
  # non-timeout network error or auth error, clear the pool and mark the
  # topology as unknown
  unknown!(
    generation: e.generation,
    service_id: e.service_id,
    stop_push_monitor: true,
  )
  raise
end

#handle_handshake_failure!

This method is for internal use only.

Handle handshake failure.

Since:

  • 2.7.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 501

def handle_handshake_failure!
  yield
rescue Mongo::Error::SocketError, Mongo::Error::SocketTimeoutError => e
  unknown!(
    generation: e.generation,
    service_id: e.service_id,
    stop_push_monitor: true,
  )
  raise
end

#heartbeat_frequency Also known as: #heartbeat_frequency_seconds

Deprecated.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 159

def heartbeat_frequency
  cluster.heartbeat_interval
end

#heartbeat_frequency_seconds

[ GitHub ]

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

alias :heartbeat_frequency_seconds :heartbeat_frequency

#inspectString

Get a pretty printed server inspection.

Examples:

Get the server inspection.

server.inspect

Returns:

  • (String)

    The nice inspection string.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 355

def inspect
  "#<Mongo::Server:0x#{object_id} address=#{address.host}:#{address.port} #{status}>"
end

#last_scanTime | nil

Returns:

  • (Time | nil)

    last_scan The time when the last server scan completed, or nil if the server has not been scanned yet.

Since:

  • 2.4.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 138

def last_scan
  if description && !description.config.empty?
    description.last_update_time
  else
    @last_scan
  end
end

#last_scan_monotimeFloat | nil

This method is for internal use only.

Returns:

  • (Float | nil)

    last_scan_monotime The monotonic time when the last server scan completed, or nil if the server has not been scanned yet.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 149

def last_scan_monotime
  if description && !description.config.empty?
    description.last_update_monotime
  else
    @last_scan_monotime
  end
end

#matches_tag_set?(tag_set) ⇒ true, false

Determine if the provided tags are a subset of the server’s tags.

Examples:

Are the provided tags a subset of the server’s tags.

server.matches_tag_set?({ 'rack' => 'a', 'dc' => 'nyc' })

Parameters:

  • tag_set (Hash)

    The tag set to compare to the server’s tags.

Returns:

  • (true, false)

    If the provided tags are a subset of the server’s tags.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 461

def matches_tag_set?(tag_set)
  tag_set.keys.all? do |k|
    tags[k] && tags[k] == tag_set[k]
  end
end

#next_connection_id

This method is for internal use only.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 680

def next_connection_id
  @connection_id_gen.next_id
end

#poolMongo::Server::ConnectionPool

Get the connection pool for this server.

Examples:

Get the connection pool for the server.

server.pool

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 424

def pool
  if unknown?
    raise Error::ServerNotUsable, address
  end

  @pool_lock.synchronize do
    opts = connected? ? options : options.merge(populator_io: false)
    @pool ||= ConnectionPool.new(self, opts).tap do |pool|
      pool.ready
    end
  end
end

#pool_internalServer::ConnectionPool | nil

This method is for internal use only.

Internal driver method to retrieve the connection pool for this server.

Unlike pool, pool_internal will not create a pool if one does not already exist.

Returns:

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 445

def pool_internal
  @pool_lock.synchronize do
    @pool
  end
end

#publish_opening_event

This method is for internal use only.

Publishes the server opening event.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 340

def publish_opening_event
  publish_sdam_event(
    Monitoring::SERVER_OPENING,
    Monitoring::Event::ServerOpening.new(address, cluster.topology)
  )
end

#reconnect!true

Restart the server monitor.

Examples:

Restart the server monitor.

server.reconnect!

Returns:

  • (true)

    Always true.

Since:

  • 2.1.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 475

def reconnect!
  if options[:monitoring_io] != false
    monitor.restart!
  end
  @connected = true
end

#start_monitoring

This method is for internal use only.

Start monitoring the server.

Used internally by the driver to add a server to a cluster while delaying monitoring until the server is in the cluster.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 330

def start_monitoring
  publish_opening_event
  if options[:monitoring_io] != false
    monitor.run!
  end
end

#statusString

This method is for internal use only.

Returns:

  • (String)

    String representing server status (e.g. PRIMARY).

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 362

def status
  case
  when load_balancer?
    'LB'
  when primary?
    'PRIMARY'
  when secondary?
    'SECONDARY'
  when standalone?
    'STANDALONE'
  when arbiter?
    'ARBITER'
  when ghost?
    'GHOST'
  when other?
    'OTHER'
  when mongos?
    'MONGOS'
  when unknown?
    'UNKNOWN'
  else
    # Since the summary method is often used for debugging, do not raise
    # an exception in case none of the expected types matched
    nil
  end
end

#summary

Note:

This method is experimental and subject to change.

Since:

  • 2.7.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 393

def summary
  status = self.status || ''
  if replica_set_name
    status += " replica_set=#{replica_set_name}"
  end

  unless monitor&.running?
    status += " NO-MONITORING"
  end

  if @pool
    status += " pool=#{@pool.summary}"
  end

  address_bit = if address
    "#{address.host}:#{address.port}"
  else
    'nil'
  end

  "#<Server address=#{address_bit} #{status}>"
end

#unknown!(options = {})

Marks server unknown and publishes the associated SDAM event (server description changed).

If the generation is passed in options, the server will only be marked unknown if the passed generation is no older than the current generation of the server’s connection pool.

Parameters:

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

Options Hash (options):

  • :generation (Integer)

    Server::Connection pool generation of the connection that was used for the operation that produced the error.

  • :keep_connection_pool (true | false)

    Usually when the new server description is unknown, the connection pool on the respective server is cleared. Set this option to true to keep the existing connection pool (required when handling not master errors on 4.2+ servers).

  • :topology_version (TopologyVersion)

    Topology version of the error response that is causing the server to be marked unknown.

  • :stop_push_monitor (true | false)

    Whether to stop the Server::PushMonitor associated with the server, if any.

  • :service_id (Object)

    Discard state for the specified service id only.

Since:

  • 2.4.0, SDAM events are sent as of version 2.7.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 592

def unknown!(options = {})
  pool = pool_internal

  if load_balancer?
    # When the client is in load-balanced topology, servers (the one and
    # only that can be) starts out as a load balancer and stays as a
    # load balancer indefinitely. As such it is not marked unknown.
    #
    # However, this method also clears connection pool for the server
    # when the latter is marked unknown, and this part needs to happen
    # when the server is a load balancer.
    #
    # It is possible for a load balancer server to not have a service id,
    # for example if there haven't been any successful connections yet to
    # this server, but the server can still be marked unknown if one
    # of such connections failed midway through its establishment.
    if service_id = options[:service_id]
      pool&.disconnect!(service_id: service_id)
    end
    return
  end

  if options[:generation] && options[:generation] < pool&.generation
    return
  end

  if options[:topology_version] && description.topology_version &&
    !options[:topology_version].gt?(description.topology_version)
  then
    return
  end

  if options[:stop_push_monitor]
    monitor&.stop_push_monitor!
  end

  # SDAM flow will update description on the server without in-place
  # mutations and invoke SDAM transitions as needed.
  config = {}
  if options[:service_id]
    config['serviceId'] = options[:service_id]
  end
  if options[:topology_version]
    config['topologyVersion'] = options[:topology_version]
  end
  new_description = Description.new(address, config,
    load_balancer: load_balancer?,
    force_load_balancer: options[:connect] == :load_balanced,
  )
  cluster.run_sdam_flow(description, new_description, options)
end

#update_description(description)

This method is for internal use only.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 645

def update_description(description)
  pool = pool_internal
  if pool && !description.unknown?
    pool.ready
  end
  @description = description
end

#update_last_scan

This method is for internal use only.

Since:

  • 2.0.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 685

def update_last_scan
  @last_scan = Time.now
  @last_scan_monotime = Utils.monotonic_time
end

#with_connection(connection_global_id: nil, &block) ⇒ Object

Execute a block of code with a connection, that is checked out of the server’s pool and then checked back in.

Examples:

Send a message with the connection.

server.with_connection do |connection|
  connection.dispatch([ command ])
end

Returns:

  • (Object)

    The result of the block execution.

Since:

  • 2.3.0

[ GitHub ]

  
# File 'lib/mongo/server.rb', line 493

def with_connection(connection_global_id: nil, &block)
  pool.with_connection(connection_global_id: connection_global_id, &block)
end