Class: Mongo::Server

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Event::Publisher, Monitoring::Publishable
Defined in:
lib/mongo/server.rb,
lib/mongo/server/context.rb,
lib/mongo/server/monitor.rb,
lib/mongo/server/connection.rb,
lib/mongo/server/description.rb,
lib/mongo/server/app_metadata.rb,
lib/mongo/server/push_monitor.rb,
lib/mongo/server/connection_base.rb,
lib/mongo/server/connection_pool.rb,
lib/mongo/server/connection_common.rb,
lib/mongo/server/monitor/connection.rb,
lib/mongo/server/pending_connection.rb,
lib/mongo/server/description/features.rb,
lib/mongo/server/monitor/app_metadata.rb,
lib/mongo/server/push_monitor/connection.rb,
lib/mongo/server/round_trip_time_averager.rb,
lib/mongo/server/connection_pool/populator.rb

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

Defined Under Namespace

Classes: AppMetadata, Connection, ConnectionBase, ConnectionCommon, ConnectionPool, Context, Description, Monitor, PendingConnection, Populator, PushMonitor, RoundTripTimeAverager

Constant Summary collapse

CONNECT_TIMEOUT =

The default time in seconds to timeout a connection attempt.

Since:

  • 2.4.3

10.freeze

Constants included from Loggable

Loggable::PREFIX

Instance Attribute Summary collapse

Attributes included from Event::Publisher

#event_listeners

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Event::Publisher

#publish

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

Constructor Details

#initialize(address, cluster, monitoring, event_listeners, options = {}) ⇒ Server

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:

Server must never be directly instantiated outside of a Cluster.

Instantiate a new server object. Will start the background refresh and subscribe to the appropriate events.

Examples:

Initialize the server.

Mongo::Server.new('127.0.0.1:27017', cluster, monitoring, listeners)

Parameters:

  • address (Address)

    The host:port address to connect to.

  • cluster (Cluster)

    The cluster the server belongs to.

  • monitoring (Monitoring)

    The monitoring.

  • event_listeners (Event::Listeners)

    The event listeners.

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

    The server options.

Options Hash (options):

  • :monitor (Boolean)

    For internal driver use only: whether to monitor the server after instantiating it.

  • :monitoring_io (true, false)

    For internal driver use only. Set to false to prevent SDAM-related I/O from being done by this server. Note: setting this option to false will make the server non-functional. It is intended for use in tests which manually invoke SDAM state transitions.

Since:

  • 2.0.0



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/mongo/server.rb', line 56

def initialize(address, cluster, monitoring, event_listeners, options = {})
  @address = address
  @cluster = cluster
  @monitoring = monitoring
  options = options.dup
  _monitor = options.delete(:monitor)
  @options = options.freeze
  @event_listeners = event_listeners
  @connection_id_gen = Class.new do
    include Id
  end
  @scan_semaphore = DistinguishingSemaphore.new
  @round_trip_time_averager = RoundTripTimeAverager.new
  @description = Description.new(address, {})
  @last_scan = nil
  unless options[:monitoring_io] == false
    @monitor = Monitor.new(self, event_listeners, monitoring,
      options.merge(
        app_metadata: Monitor::.new(cluster.options),
        heartbeat_interval: cluster.heartbeat_interval,
    ))
    unless _monitor == false
      start_monitoring
    end
  end
  @connected = true
  @pool_lock = Mutex.new
end

Instance Attribute Details

#addressString (readonly)

Returns The configured address for the server.

Returns:

  • (String)

    The configured address for the server.

Since:

  • 2.0.0



86
87
88
# File 'lib/mongo/server.rb', line 86

def address
  @address
end

#clusterCluster (readonly)

Returns cluster The server cluster.

Returns:

  • (Cluster)

    cluster The server cluster.

Since:

  • 2.0.0



89
90
91
# File 'lib/mongo/server.rb', line 89

def cluster
  @cluster
end

#descriptionServer::Description (readonly)

Returns description The server description the monitor refreshes.

Returns:

Since:

  • 2.0.0



103
104
105
# File 'lib/mongo/server.rb', line 103

def description
  @description
end

#monitornil | Monitor (readonly)

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

Returns:

  • (nil | Monitor)

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

Since:

  • 2.0.0



93
94
95
# File 'lib/mongo/server.rb', line 93

def monitor
  @monitor
end

#monitoringMonitoring (readonly)

Returns monitoring The monitoring.

Returns:

Since:

  • 2.0.0



99
100
101
# File 'lib/mongo/server.rb', line 99

def monitoring
  @monitoring
end

#optionsHash (readonly)

Returns The options hash.

Returns:

  • (Hash)

    The options hash.

Since:

  • 2.0.0



96
97
98
# File 'lib/mongo/server.rb', line 96

def options
  @options
end

#round_trip_time_averagerRoundTripTimeAverager (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 Round trip time averager object.

Returns:

Since:

  • 2.0.0



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

def round_trip_time_averager
  @round_trip_time_averager
end

#scan_semaphoreSemaphore (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 Semaphore to signal to request an immediate scan of this server by its monitor, if one is running.

Returns:

  • (Semaphore)

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

Since:

  • 2.0.0



182
183
184
# File 'lib/mongo/server.rb', line 182

def scan_semaphore
  @scan_semaphore
end

Class Method Details

.finalize(monitor) ⇒ Object

When the server is flagged for garbage collection, stop the monitor thread.

Examples:

Finalize the object.

Server.finalize(monitor)

Parameters:

Since:

  • 2.2.0



284
285
286
# File 'lib/mongo/server.rb', line 284

def self.finalize(monitor)
  proc { monitor.stop! }
end

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



198
199
200
201
# File 'lib/mongo/server.rb', line 198

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

#clear_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.

Since:

  • 2.0.0



541
542
543
544
545
546
547
# File 'lib/mongo/server.rb', line 541

def clear_connection_pool
  @pool_lock.synchronize do
    if @pool
      @pool.disconnect!
    end
  end
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



140
141
142
143
144
145
146
# File 'lib/mongo/server.rb', line 140

def compressor
  if monitor
    monitor.compressor
  else
    nil
  end
end

#connectable?true, false

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



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

def connectable?; end

#connected?true|false

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 server is connected.

Returns:

  • (true|false)

    Whether the server is connected.

Since:

  • 2.7.0



271
272
273
# File 'lib/mongo/server.rb', line 271

def connected?
  @connected
end

#contextMongo::Server::Context

Deprecated.

Will be removed in version 3.0

Get a new context for this server in which to send messages.

Examples:

Get the server context.

server.context

Returns:

Since:

  • 2.0.0



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

def context
  Context.new(self)
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



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/mongo/server.rb', line 242

def disconnect!
  if monitor
    monitor.stop!
  end
  _pool = @pool_lock.synchronize do
    @pool
  end
  if _pool
    # For backwards compatibility we disconnect/clear the pool rather
    # than close it here. We also stop the populator which allows the
    # the pool to continue providing connections but stops it from
    # connecting in background on clients/servers that are in fact
    # intended to be closed and no longer used.
    begin
      _pool.disconnect!(stop_populator: true)
    rescue Error::PoolClosedError
      # If the pool was already closed, we don't need to do anything here.
    end
  end
  @connected = false
  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



451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/mongo/server.rb', line 451

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

#handle_handshake_failure!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.

Handle handshake failure.

Since:

  • 2.7.0



432
433
434
435
436
437
# File 'lib/mongo/server.rb', line 432

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

#heartbeat_frequencyObject Also known as: heartbeat_frequency_seconds

Deprecated.

Since:

  • 2.0.0



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

def heartbeat_frequency
  cluster.heartbeat_interval
end

#inspectString

Get a pretty printed server inspection.

Examples:

Get the server inspection.

server.inspect

Returns:

  • (String)

    The nice inspection string.

Since:

  • 2.0.0



313
314
315
# File 'lib/mongo/server.rb', line 313

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

#last_scanTime | nil

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

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



109
110
111
112
113
114
115
# File 'lib/mongo/server.rb', line 109

def last_scan
  if description && !description.config.empty?
    description.last_update_time
  else
    @last_scan
  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



392
393
394
395
396
# File 'lib/mongo/server.rb', line 392

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

#next_connection_idObject

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



550
551
552
# File 'lib/mongo/server.rb', line 550

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



376
377
378
379
380
# File 'lib/mongo/server.rb', line 376

def pool
  @pool_lock.synchronize do
    @pool ||= ConnectionPool.new(self, options)
  end
end

#reconnect!true

Restart the server monitor.

Examples:

Restart the server monitor.

server.reconnect!

Returns:

  • (true)

    Always true.

Since:

  • 2.1.0



406
407
408
409
410
411
# File 'lib/mongo/server.rb', line 406

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

#retry_reads?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 server supports modern read retries.

Returns:

  • (Boolean)

Since:

  • 2.0.0



469
470
471
# File 'lib/mongo/server.rb', line 469

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

#retry_writes?true, false

Note:

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

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



484
485
486
# File 'lib/mongo/server.rb', line 484

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

#start_monitoringObject

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.

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



294
295
296
297
298
299
300
301
302
303
# File 'lib/mongo/server.rb', line 294

def start_monitoring
  publish_sdam_event(
    Monitoring::SERVER_OPENING,
    Monitoring::Event::ServerOpening.new(address, cluster.topology)
  )
  if options[:monitoring_io] != false
    ObjectSpace.define_finalizer(self, self.class.finalize(monitor))
    monitor.run!
  end
end

#statusString

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 String representing server status (e.g. PRIMARY).

Returns:

  • (String)

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

Since:

  • 2.0.0



320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/mongo/server.rb', line 320

def status
  case
  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

#summaryObject

Note:

This method is experimental and subject to change.

Since:

  • 2.7.0



349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/mongo/server.rb', line 349

def summary
  status = self.status || ''
  if replica_set_name
    status += " replica_set=#{replica_set_name}"
  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 = {}) ⇒ Object

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.

Options Hash (options):

  • :generation (Integer)

    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 PushMonitor associated with the server, if any.

Since:

  • 2.4.0, SDAM events are sent as of version 2.7.0



510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
# File 'lib/mongo/server.rb', line 510

def unknown!(options = {})
  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[:topology_version]
    config['topologyVersion'] = options[:topology_version]
  end
  new_description = Description.new(address, config)
  cluster.run_sdam_flow(description, new_description, options)
end

#update_description(description) ⇒ 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



536
537
538
# File 'lib/mongo/server.rb', line 536

def update_description(description)
  @description = description
end

#update_last_scanObject

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



555
556
557
# File 'lib/mongo/server.rb', line 555

def update_last_scan
  @last_scan = Time.now
end

#with_connection(&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



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

def with_connection(&block)
  pool.with_connection(&block)
end