Class: Mongo::Server::Monitor Private

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
BackgroundThread, Event::Publisher, Loggable
Defined in:
lib/mongo/server/monitor.rb,
lib/mongo/server/monitor/connection.rb,
lib/mongo/server/monitor/app_metadata.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Responsible for periodically polling a server via ismaster 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.

Since:

  • 2.0.0

API:

  • private

Defined Under Namespace

Classes: AppMetadata, Connection

Constant Summary collapse

DEFAULT_HEARTBEAT_INTERVAL =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The default interval between server status refreshes is 10 seconds.

Since:

  • 2.0.0

API:

  • private

10.freeze
MIN_SCAN_INTERVAL =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

The minimum time between forced server scans. Is minHeartbeatFrequencyMS in the SDAM spec.

Since:

  • 2.0.0

API:

  • private

0.5.freeze
RTT_WEIGHT_FACTOR =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Deprecated.

Will be removed in version 3.0.

The weighting factor (alpha) for calculating the average moving round trip time.

Since:

  • 2.0.0

API:

  • private

0.2.freeze

Constants included from Loggable

Loggable::PREFIX

Instance Attribute Summary collapse

Attributes included from Event::Publisher

#event_listeners

Instance Method Summary collapse

Methods included from BackgroundThread

#run!, #running?

Methods included from Loggable

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

Methods included from Event::Publisher

#publish

Constructor Details

#initialize(server, event_listeners, monitoring, options = {}) ⇒ Monitor

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:

Monitor must never be directly instantiated outside of a Server.

Create the new server monitor.

Examples:

Create the server monitor.

Mongo::Server::Monitor.new(address, listeners, monitoring)

Parameters:

  • The server to monitor.

  • The event listeners.

  • The monitoring..

  • (defaults to: {})

    The options.

Options Hash (options):

  • :connect_timeout (Float)

    The timeout, in seconds, to use when establishing the monitoring connection.

  • :heartbeat_interval (Float)

    The interval between regular server checks.

  • :logger (Logger)

    A custom logger to use.

  • :socket_timeout (Float)

    The timeout, in seconds, to execute operations on the monitoring connection.

Since:

  • 2.0.0

API:

  • private



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/mongo/server/monitor.rb', line 71

def initialize(server, event_listeners, monitoring, options = {})
  unless monitoring.is_a?(Monitoring)
    raise ArgumentError, "Wrong monitoring type: #{monitoring.inspect}"
  end
  @server = server
  @event_listeners = event_listeners
  @monitoring = monitoring
  @options = options.freeze
  @mutex = Mutex.new
  @sdam_mutex = Mutex.new
  @next_earliest_scan = @next_wanted_scan = Time.now
  @update_mutex = Mutex.new
end

Instance Attribute Details

#connectionMongo::Server::Monitor::Connection (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 connection The connection to use.

Returns:

  • connection The connection to use.

Since:

  • 2.0.0

API:

  • private



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

def connection
  @connection
end

#monitoringMonitoring (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 monitoring The monitoring.

Returns:

  • monitoring The monitoring.

Since:

  • 2.0.0

API:

  • private



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

def monitoring
  @monitoring
end

#optionsHash (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 options The server options.

Returns:

  • options The server options.

Since:

  • 2.0.0

API:

  • private



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

def options
  @options
end

#serverServer (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 server The server that this monitor is monitoring.

Returns:

  • server The server that this monitor is monitoring.

Since:

  • 2.0.0

API:

  • private



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

def server
  @server
end

Instance Method Details

#do_workThread

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.

Runs the server monitor. Refreshing happens on a separate thread per server.

Examples:

Run the monitor.

monitor.run

Returns:

  • The thread the monitor runs on.

Since:

  • 2.0.0

API:

  • private



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/mongo/server/monitor.rb', line 131

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_intervalFloat

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 interval between regular server checks.

Returns:

  • The heartbeat interval, in seconds.

Since:

  • 2.0.0

API:

  • private



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

def heartbeat_interval
  options[:heartbeat_interval] || DEFAULT_HEARTBEAT_INTERVAL
end

#push_monitorServer::PushMonitor | 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.

Returns The push monitor, if one is being used.

Returns:

  • The push monitor, if one is being used.

Since:

  • 2.0.0

API:

  • private



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

def push_monitor
  @update_mutex.synchronize do
    @push_monitor
  end
end

#restart!Thread

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.

Restarts the server monitor unless the current thread is alive.

Examples:

Restart the monitor.

monitor.restart!

Returns:

  • The thread the monitor runs on.

Since:

  • 2.1.0

API:

  • private



236
237
238
239
240
241
242
# File 'lib/mongo/server/monitor.rb', line 236

def restart!
  if @thread && @thread.alive?
    @thread
  else
    run!
  end
end

#run_sdam_flow(result, awaited: false) ⇒ 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

API:

  • private



206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/mongo/server/monitor.rb', line 206

def run_sdam_flow(result, awaited: false)
  @sdam_mutex.synchronize do
    old_description = server.description

    new_description = Description.new(server.address, result,
      server.round_trip_time_averager.average_round_trip_time)

    server.cluster.run_sdam_flow(server.description, new_description, awaited: awaited)

    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

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:

If the system clock moves backwards, this method can sleep for a very long time.

Note:

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 isMaster on the server being monitored and updating the server description as a result.

Returns:

  • The updated description.

Since:

  • 2.0.0

API:

  • private



193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/mongo/server/monitor.rb', line 193

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!

    result = do_scan

    run_sdam_flow(result)
  end
end

#stop!true | false

Stop the background thread and wait for it to terminate for a reasonable amount of time.

Returns:

  • Whether the thread was terminated.

Since:

  • 2.0.0

API:

  • public for backwards compatibility only



155
156
157
158
159
160
161
162
163
164
# File 'lib/mongo/server/monitor.rb', line 155

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!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

API:

  • private



166
167
168
169
170
171
172
173
# File 'lib/mongo/server/monitor.rb', line 166

def stop_push_monitor!
  @update_mutex.synchronize do
    if @push_monitor
      @push_monitor.stop!
      @push_monitor = nil
    end
  end
end