Class: Mongo::Server::Monitor Private
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Forwardable
|
|
Instance Chain:
|
|
Inherits: | Object |
Defined in: | lib/mongo/server/monitor.rb, lib/mongo/server/monitor/app_metadata.rb, lib/mongo/server/monitor/connection.rb |
Overview
Responsible for periodically polling a server via hello commands to keep the server’s status up to date.
Does all work in a background thread so as to not interfere with other operations performed by the driver.
Constant Summary
-
DEFAULT_HEARTBEAT_INTERVAL =
The default interval between server status refreshes is 10 seconds.
10.freeze
-
MIN_SCAN_INTERVAL =
The minimum time between forced server scans. Is minHeartbeatFrequencyMS in the SDAM spec.
0.5.freeze
-
RTT_WEIGHT_FACTOR =
Deprecated.
Will be removed in version 3.0.
The weighting factor (alpha) for calculating the average moving round trip time.
0.2.freeze
::Mongo::Loggable
- Included
Class Method Summary
-
.new(server, event_listeners, monitoring, options = {}) ⇒ Monitor
constructor
Internal use only
Create the new server monitor.
Instance Attribute Summary
- #connection ⇒ Mongo::Server::Monitor::Connection readonly Internal use only
- #monitoring ⇒ Monitoring readonly Internal use only
- #options ⇒ Hash readonly Internal use only
- #server ⇒ Server readonly Internal use only
::Mongo::BackgroundThread
- Included
::Mongo::Event::Publisher
- Included
Instance Method Summary
- #create_push_monitor!(topology_version) Internal use only
-
#do_work
Internal use only
Perform a check of the server.
-
#heartbeat_interval ⇒ Float
Internal use only
The interval between regular server checks.
- #push_monitor ⇒ Server::PushMonitor | nil Internal use only
-
#restart! ⇒ Thread
Internal use only
Restarts the server monitor unless the current thread is alive.
- #run_sdam_flow(result, awaited: false, scan_error: nil) Internal use only
-
#scan! ⇒ Description
Internal use only
Perform a check of the server with throttling, and update the server’s description and average round trip time.
-
#stop! ⇒ true | false
Stop the background thread and wait for it to terminate for a reasonable amount of time.
- #stop_push_monitor! Internal use only
- #to_s Internal use only
- #check private Internal use only
- #do_scan private Internal use only
- #pre_stop private Internal use only
- #throttle_scan_frequency! private Internal use only
::Mongo::BackgroundThread
- Included
#run! | Start the background thread. |
#stop! | Stop the background thread and wait for to terminate for a reasonable amount of time. |
#do_work | Override this method to do the work in the background thread. |
#pre_stop | Override this method to perform additional signaling for the background thread to stop. |
#start!, | |
#wait_for_stop | Waits for the thread to die, with a timeout. |
::Mongo::Event::Publisher
- Included
#publish | Publish the provided event. |
::Mongo::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
#connection ⇒ Mongo::Server::Monitor::Connection (readonly)
# File 'lib/mongo/server/monitor.rb', line 103
attr_reader :connection
#monitoring ⇒ Monitoring (readonly)
# File 'lib/mongo/server/monitor.rb', line 125
attr_reader :monitoring
#options ⇒ Hash
(readonly)
# File 'lib/mongo/server/monitor.rb', line 106
attr_reader :
#server ⇒ Server (readonly)
# File 'lib/mongo/server/monitor.rb', line 100
attr_reader :server
Instance Method Details
#check (private)
# File 'lib/mongo/server/monitor.rb', line 304
def check if @connection && @connection.pid != Process.pid log_warn("Detected PID change - Mongo client should have been reconnected (old pid #{@connection.pid}, new pid #{Process.pid}") @connection.disconnect! @connection = nil end if @connection result = server.round_trip_time_calculator.measure do begin doc = @connection.check_document cmd = Protocol::Query.new( Database::ADMIN, Database::COMMAND, doc, :limit => -1 ) = @connection.dispatch_bytes(cmd.serialize.to_s) .documents.first rescue Mongo::Error @connection.disconnect! @connection = nil raise end end else connection = Connection.new(server.address, ) connection.connect! result = server.round_trip_time_calculator.measure do connection.handshake! end @connection = connection if tv_doc = result['topologyVersion'] # Successful response, server 4.4+ create_push_monitor!(TopologyVersion.new(tv_doc)) push_monitor.run! else # Failed response or pre-4.4 server stop_push_monitor! end result end result end
#create_push_monitor!(topology_version)
# File 'lib/mongo/server/monitor.rb', line 173
def create_push_monitor!(topology_version) @update_mutex.synchronize do if @push_monitor && !@push_monitor.running? @push_monitor = nil end @push_monitor ||= PushMonitor.new( self, topology_version, monitoring, **Utils.shallow_symbolize_keys( .merge( socket_timeout: heartbeat_interval + connection.socket_timeout, app_metadata: [: ], check_document: @connection.check_document )), ) end end
#do_scan (private)
# File 'lib/mongo/server/monitor.rb', line 288
def do_scan begin monitoring.publish_heartbeat(server) do check end rescue => exc msg = "Error checking #{server.address}" Utils.warn_bg_exception(msg, exc, logger: [:logger], log_prefix: [:log_prefix], bg_error_backtrace: [:bg_error_backtrace], ) raise exc end end
#do_work
Perform a check of the server.
# File 'lib/mongo/server/monitor.rb', line 138
def do_work scan! # @next_wanted_scan may be updated by the push monitor. # However we need to check for termination flag so that the monitor # thread exits when requested. loop do delta = @next_wanted_scan - Time.now if delta > 0 signaled = server.scan_semaphore.wait(delta) if signaled || @stop_requested break end else break end end end
#heartbeat_interval ⇒ Float
The interval between regular server checks.
# File 'lib/mongo/server/monitor.rb', line 111
def heartbeat_interval [:heartbeat_interval] || DEFAULT_HEARTBEAT_INTERVAL end
#pre_stop (private)
# File 'lib/mongo/server/monitor.rb', line 284
def pre_stop server.scan_semaphore.signal end
#push_monitor ⇒ Server::PushMonitor | nil
# File 'lib/mongo/server/monitor.rb', line 129
def push_monitor @update_mutex.synchronize do @push_monitor end end
#restart! ⇒ Thread
Restarts the server monitor unless the current thread is alive.
# File 'lib/mongo/server/monitor.rb', line 270
def restart! if @thread && @thread.alive? @thread else run! end end
#run_sdam_flow(result, awaited: false, scan_error: nil)
# File 'lib/mongo/server/monitor.rb', line 236
def run_sdam_flow(result, awaited: false, scan_error: nil) @sdam_mutex.synchronize do old_description = server.description new_description = Description.new( server.address, result, average_round_trip_time: server.round_trip_time_calculator.average_round_trip_time, minimum_round_trip_time: server.round_trip_time_calculator.minimum_round_trip_time ) server.cluster.run_sdam_flow(server.description, new_description, awaited: awaited, scan_error: scan_error) server.description.tap do |new_description| unless awaited if new_description.unknown? && !old_description.unknown? @next_earliest_scan = @next_wanted_scan = Time.now else @next_earliest_scan = Time.now + MIN_SCAN_INTERVAL @next_wanted_scan = Time.now + heartbeat_interval end end end end end
#scan! ⇒ Description
If the system clock moves backwards, this method can sleep for a very long time.
The return value of this method is deprecated. In version 3.0.0 this method will not have a return value.
Perform a check of the server with throttling, and update the server’s description and average round trip time.
If the server was checked less than MIN_SCAN_INTERVAL seconds ago, sleep until MIN_SCAN_INTERVAL seconds have passed since the last check. Then perform the check which involves running hello on the server being monitored and updating the server description as a result.
# File 'lib/mongo/server/monitor.rb', line 219
def scan! # Ordinarily the background thread would invoke this method. # But it is also possible to invoke scan! directly on a monitor. # Allow only one scan to be performed at a time. @mutex.synchronize do throttle_scan_frequency! begin result = do_scan rescue => e run_sdam_flow({}, scan_error: e) else run_sdam_flow(result) end end end
#stop! ⇒ true
| false
Stop the background thread and wait for it to terminate for a reasonable amount of time.
# File 'lib/mongo/server/monitor.rb', line 162
def stop! stop_push_monitor! # Forward super's return value super.tap do # Important: disconnect should happen after the background thread # terminates. connection&.disconnect! end end
#stop_push_monitor!
# File 'lib/mongo/server/monitor.rb', line 192
def stop_push_monitor! @update_mutex.synchronize do if @push_monitor @push_monitor.stop! @push_monitor = nil end end end
#throttle_scan_frequency! (private)
If the system clock is set to a time in the past, this method can sleep for a very long time.
# File 'lib/mongo/server/monitor.rb', line 348
def throttle_scan_frequency! delta = @next_earliest_scan - Time.now if delta > 0 sleep(delta) end end