Class: Mongo::Server
Overview
Represents a single server on the server side that can be standalone, part of a replica set, or a mongos.
Constant Summary
-
CONNECT_TIMEOUT =
The default time in seconds to timeout a connection attempt.
10.freeze
Loggable
- Included
Class Method Summary
-
.new(address, cluster, monitoring, event_listeners, options = {}) ⇒ Server
constructor
Internal use only
Internal use only
Instantiate a new server object.
Instance Attribute Summary
- #address ⇒ String readonly
- #cluster ⇒ Cluster readonly
-
#connectable? ⇒ true, false
readonly
deprecated
Deprecated.
No longer necessary with
Server
Selection specification. -
#connected? ⇒ true|false
readonly
Internal use only
Internal use only
Whether the server is connected.
- #description ⇒ Server::Description readonly
-
#force_load_balancer? ⇒ true | false
readonly
Internal use only
Internal use only
Returns whether this server is forced to be a load balancer.
- #monitor ⇒ nil | Monitor readonly
- #monitoring ⇒ Monitoring readonly
- #options ⇒ Hash readonly
-
#retry_reads? ⇒ Boolean
readonly
Internal use only
Internal use only
Whether the server supports modern read retries.
-
#retry_writes? ⇒ true, false
readonly
Will writes sent to this server be retried.
- #round_trip_time_calculator ⇒ RoundTripTimeCalculator readonly Internal use only Internal use only
- #scan_semaphore ⇒ Semaphore readonly Internal use only Internal use only
Event::Publisher
- Included
Monitoring::Publishable
- Included
Instance Method Summary
-
#==(other) ⇒ true, false
Is this server equal to another?
- #clear_connection_pool(service_id: nil, interrupt_in_use_connections: false) Internal use only Internal use only
-
#clear_description
Internal use only
Internal use only
Clear the servers description so that it is considered unknown and can be safely disconnected.
- #close
- #compressor ⇒ String | nil deprecated Deprecated.
-
#disconnect! ⇒ true
Disconnect the driver from this server.
-
#handle_auth_failure! ⇒ Object
Handle authentication failure.
-
#handle_handshake_failure!
Internal use only
Internal use only
Handle handshake failure.
- #heartbeat_frequency (also: #heartbeat_frequency_seconds) deprecated Deprecated.
-
#heartbeat_frequency_seconds
Alias for #heartbeat_frequency.
-
#inspect ⇒ String
Get a pretty printed server inspection.
- #last_scan ⇒ Time | nil
- #last_scan_monotime ⇒ Float | nil Internal use only Internal use only
-
#matches_tag_set?(tag_set) ⇒ true, false
Determine if the provided tags are a subset of the server’s tags.
- #next_connection_id Internal use only Internal use only
-
#pool ⇒ Mongo::Server::ConnectionPool
Get the connection pool for this server.
-
#pool_internal ⇒ Server::ConnectionPool | nil
Internal use only
Internal use only
Internal driver method to retrieve the connection pool for this server.
-
#publish_opening_event
Internal use only
Internal use only
Publishes the server opening event.
-
#reconnect! ⇒ true
Restart the server monitor.
-
#start_monitoring
Internal use only
Internal use only
Start monitoring the server.
- #status ⇒ String Internal use only Internal use only
- #summary
-
#unknown!(options = {})
Marks server unknown and publishes the associated SDAM event (server description changed).
- #update_description(description) Internal use only Internal use only
- #update_last_scan Internal use only Internal use only
-
#with_connection(connection_global_id: nil, context: 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.
Event::Publisher
- Included
#publish | Publish the provided event. |
Monitoring::Publishable
- Included
#publish_cmap_event, #publish_event, #publish_sdam_event, #command_completed, #command_failed, #command_started, #command_succeeded, #duration |
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
#address ⇒ String
(readonly)
# File 'lib/mongo/server.rb', line 106
attr_reader :address
#cluster ⇒ Cluster (readonly)
# File 'lib/mongo/server.rb', line 109
attr_reader :cluster
#connectable? ⇒ true
, false
(readonly)
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.
# File 'lib/mongo/server.rb', line 262
def connectable?; end
#connected? ⇒ true
|false
(readonly)
Whether the server is connected.
# File 'lib/mongo/server.rb', line 321
def connected? @connected end
#description ⇒ Server::Description (readonly)
# File 'lib/mongo/server.rb', line 123
attr_reader :description
#force_load_balancer? ⇒ true
| false
(readonly)
Returns whether this server is forced to be a load balancer.
# File 'lib/mongo/server.rb', line 130
def force_load_balancer? [:connect] == :load_balanced end
#monitor ⇒ nil
| Monitor (readonly)
# File 'lib/mongo/server.rb', line 113
attr_reader :monitor
#monitoring ⇒ Monitoring (readonly)
# File 'lib/mongo/server.rb', line 119
attr_reader :monitoring
#options ⇒ Hash
(readonly)
# File 'lib/mongo/server.rb', line 116
attr_reader :
#retry_reads? ⇒ Boolean
(readonly)
Whether the server supports modern read retries.
# File 'lib/mongo/server.rb', line 548
def retry_reads? !!(features.sessions_enabled? && logical_session_timeout) end
#retry_writes? ⇒ true
, false
(readonly)
Retryable
writes are only available on server versions 3.6+ and with sharded clusters or replica sets.
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.
# File 'lib/mongo/server.rb', line 569
def retry_writes? !!(features.sessions_enabled? && logical_session_timeout && !standalone?) || load_balancer? end
#round_trip_time_calculator ⇒ RoundTripTimeCalculator (readonly)
# File 'lib/mongo/server.rb', line 234
attr_reader :round_trip_time_calculator
#scan_semaphore ⇒ Semaphore (readonly)
# File 'lib/mongo/server.rb', line 230
attr_reader :scan_semaphore
Instance Method Details
#==(other) ⇒ true
, false
Is this server equal to another?
#clear_connection_pool(service_id: nil, interrupt_in_use_connections: false)
# File 'lib/mongo/server.rb', line 672
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
Clear the servers description so that it is considered unknown and can be safely disconnected.
# File 'lib/mongo/server.rb', line 662
def clear_description @description = Mongo::Server::Description.new(address, {}) end
#close
# File 'lib/mongo/server.rb', line 295
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
#compressor ⇒ String
| nil
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.
#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.
# File 'lib/mongo/server.rb', line 276
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.
# File 'lib/mongo/server.rb', line 529
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!
Handle handshake failure.
# File 'lib/mongo/server.rb', line 506
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
# File 'lib/mongo/server.rb', line 159
def heartbeat_frequency cluster.heartbeat_interval end
#heartbeat_frequency_seconds
Alias for #heartbeat_frequency.
# File 'lib/mongo/server.rb', line 164
alias :heartbeat_frequency_seconds :heartbeat_frequency
#inspect ⇒ String
Get a pretty printed server inspection.
#last_scan ⇒ Time
| nil
# 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_monotime ⇒ Float
| nil
# 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.
# File 'lib/mongo/server.rb', line 462
def matches_tag_set?(tag_set) tag_set.keys.all? do |k| [k] && [k] == tag_set[k] end end
#next_connection_id
# File 'lib/mongo/server.rb', line 685
def next_connection_id @connection_id_gen.next_id end
#pool ⇒ Mongo::Server::ConnectionPool
Get the connection pool for this server.
# File 'lib/mongo/server.rb', line 425
def pool if unknown? raise Error::ServerNotUsable, address end @pool_lock.synchronize do opts = connected? ? : .merge(populator_io: false) @pool ||= ConnectionPool.new(self, opts).tap do |pool| pool.ready end end end
#pool_internal ⇒ Server::ConnectionPool | nil
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.
# File 'lib/mongo/server.rb', line 446
def pool_internal @pool_lock.synchronize do @pool end end
#publish_opening_event
Publishes the server opening event.
# File 'lib/mongo/server.rb', line 341
def publish_opening_event publish_sdam_event( Monitoring::SERVER_OPENING, Monitoring::Event::ServerOpening.new(address, cluster.topology) ) end
#reconnect! ⇒ true
Restart the server monitor.
# File 'lib/mongo/server.rb', line 476
def reconnect! if [:monitoring_io] != false monitor.restart! end @connected = true end
#start_monitoring
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.
# File 'lib/mongo/server.rb', line 331
def start_monitoring publish_opening_event if [:monitoring_io] != false monitor.run! end end
#status ⇒ String
# File 'lib/mongo/server.rb', line 363
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
This method is experimental and subject to change.
# File 'lib/mongo/server.rb', line 394
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.
# File 'lib/mongo/server.rb', line 597
def unknown!( = {}) 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 = [:service_id] pool&.disconnect!(service_id: service_id) end return end if [:generation] && [:generation] < pool&.generation return end if [:topology_version] && description.topology_version && ! [:topology_version].gt?(description.topology_version) then return end if [: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 [:service_id] config['serviceId'] = [:service_id] end if [:topology_version] config['topologyVersion'] = [:topology_version] end new_description = Description.new(address, config, load_balancer: load_balancer?, force_load_balancer: [:connect] == :load_balanced, ) cluster.run_sdam_flow(description, new_description, ) end
#update_description(description)
# File 'lib/mongo/server.rb', line 650
def update_description(description) pool = pool_internal if pool && !description.unknown? pool.ready end @description = description end
#update_last_scan
# File 'lib/mongo/server.rb', line 690
def update_last_scan @last_scan = Time.now @last_scan_monotime = Utils.monotonic_time end
#with_connection(connection_global_id: nil, context: 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.
# File 'lib/mongo/server.rb', line 494
def with_connection(connection_global_id: nil, context: nil, &block) pool.with_connection( connection_global_id: connection_global_id, context: context, &block ) end