Class: Mongo::ServerSelector::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/mongo/server_selector/base.rb

Overview

Since:

  • 2.0.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = nil) ⇒ Base

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.

Initialize the server selector.

Examples:

Initialize the selector.

Mongo::ServerSelector::Secondary.new(:tag_sets => [{'dc' => 'nyc'}])

Initialize the preference with no options.

Mongo::ServerSelector::Secondary.new

Parameters:

  • options (Hash) (defaults to: nil)

    The server preference options.

Options Hash (options):

  • :local_threshold (Integer)

    The local threshold boundary for nearest selection in seconds.

  • :max_staleness (Integer)

    The maximum replication lag, in seconds, that a secondary can suffer and still be eligible for a read. A value of -1 is treated identically to nil, which is to not have a maximum staleness.

  • :hedge (Hash | nil)

    A Hash specifying whether to enable hedged reads on the server. Hedged reads are not enabled by default. When specifying this option, it must be in the format: { enabled: true }, where the value of the :enabled key is a boolean value.

Raises:

Since:

  • 2.0.0



45
46
47
48
49
50
51
52
53
54
# File 'lib/mongo/server_selector/base.rb', line 45

def initialize(options = nil)
  options = options ? options.dup : {}
  options.delete(:max_staleness) if options[:max_staleness] == -1
  @options = options
  @tag_sets = options[:tag_sets] || []
  @max_staleness = options[:max_staleness]
  @hedge = options[:hedge]

  validate!
end

Instance Attribute Details

#hedgeHash | nil (readonly)

Returns hedge The document specifying whether to enable hedged reads.

Returns:

  • (Hash | nil)

    hedge The document specifying whether to enable hedged reads.

Since:

  • 2.0.0



70
71
72
# File 'lib/mongo/server_selector/base.rb', line 70

def hedge
  @hedge
end

#max_stalenessInteger (readonly)

Returns max_staleness The maximum replication lag, in seconds, that a secondary can suffer and still be eligible for a read.

Returns:

  • (Integer)

    max_staleness The maximum replication lag, in seconds, that a secondary can suffer and still be eligible for a read.

Since:

  • 2.4.0



66
67
68
# File 'lib/mongo/server_selector/base.rb', line 66

def max_staleness
  @max_staleness
end

#optionsHash (readonly)

Returns options The options.

Returns:

  • (Hash)

    options The options.

Since:

  • 2.0.0



57
58
59
# File 'lib/mongo/server_selector/base.rb', line 57

def options
  @options
end

#tag_setsArray (readonly)

Returns tag_sets The tag sets used to select servers.

Returns:

  • (Array)

    tag_sets The tag sets used to select servers.

Since:

  • 2.0.0



60
61
62
# File 'lib/mongo/server_selector/base.rb', line 60

def tag_sets
  @tag_sets
end

Instance Method Details

#==(other) ⇒ true, false

Check equality of two server selectors.

Examples:

Check server selector equality.

preference == other

Parameters:

  • other (Object)

    The other preference.

Returns:

  • (true, false)

    Whether the objects are equal.

Since:

  • 2.0.0



130
131
132
133
# File 'lib/mongo/server_selector/base.rb', line 130

def ==(other)
  name == other.name && hedge == other.hedge &&
    max_staleness == other.max_staleness && tag_sets == other.tag_sets
end

#candidates(cluster, deprioritized = []) ⇒ Array<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.

Returns servers of acceptable types from the cluster.

Does not perform staleness validation, staleness filtering or latency filtering.

Parameters:

  • cluster (Cluster)

    The cluster.

  • deprioritized (Array<Server>) (defaults to: [])

    A list of servers that should be selected from only if no other servers are available.

Returns:

  • (Array<Server>)

    The candidate servers.

Since:

  • 2.0.0



386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/mongo/server_selector/base.rb', line 386

def candidates(cluster, deprioritized = [])
  servers = cluster.servers.reject { |s| deprioritized.include?(s) }
  if cluster.single?
    servers
  elsif cluster.sharded?
    servers
  elsif cluster.replica_set?
    select_in_replica_set(servers)
  else
    # Unknown cluster - no servers
    []
  end
end

#inspectString

Inspect the server selector.

Examples:

Inspect the server selector.

selector.inspect

Returns:

  • (String)

    The inspection.

Since:

  • 2.2.0



116
117
118
# File 'lib/mongo/server_selector/base.rb', line 116

def inspect
  "#<#{self.class.name}:0x#{object_id} tag_sets=#{tag_sets.inspect} max_staleness=#{max_staleness.inspect} hedge=#{hedge}>"
end

#local_thresholdFloat

Deprecated.

This setting is now taken from the cluster options when a server is selected. Will be removed in version 3.0.

Get the local threshold boundary for nearest selection in seconds.

Examples:

Get the local threshold.

selector.local_threshold

Returns:

  • (Float)

    The local threshold.

Since:

  • 2.0.0



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

def local_threshold
  @local_threshold ||= options[:local_threshold] || ServerSelector::LOCAL_THRESHOLD
end

#local_threshold_with_cluster(cluster) ⇒ 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



104
105
106
# File 'lib/mongo/server_selector/base.rb', line 104

def local_threshold_with_cluster(cluster)
  options[:local_threshold] || cluster.options[:local_threshold] || LOCAL_THRESHOLD
end

#select_server(cluster, ping = nil, session = nil, write_aggregation: false, deprioritized: [], timeout: nil) ⇒ Mongo::Server

Select a server from the specified cluster, taking into account mongos pinning for the specified session.

If the session is given and has a pinned server, this server is the only server considered for selection. If the server is of type mongos, it is returned immediately; otherwise monitoring checks on this server are initiated to update its status, and if the server becomes a mongos within the server selection timeout, it is returned.

If no session is given or the session does not have a pinned server, normal server selection process is performed among all servers in the specified cluster matching the preference of this server selector object. Monitoring checks are initiated on servers in the cluster until a suitable server is found, up to the server selection timeout.

If a suitable server is not found within the server selection timeout, this method raises Error::NoServerAvailable.

Parameters:

  • cluster (Mongo::Cluster)

    The cluster from which to select an eligible server.

  • ping (true, false) (defaults to: nil)

    Whether to ping the server before selection. Deprecated and ignored.

  • session (Session | nil) (defaults to: nil)

    Optional session to take into account for mongos pinning.

  • write_aggregation (true | false) (defaults to: false)

    Whether we need a server that supports writing aggregations (e.g. with $merge/$out) on secondaries.

  • deprioritized (Array<Server>) (defaults to: [])

    A list of servers that should be selected from only if no other servers are available.

  • :timeout (Float | nil)

    Timeout in seconds for the operation, if any.

Returns:

Raises:

  • (Error::NoServerAvailable)

    No server was found matching the specified preference / pinning requirement in the server selection timeout.

  • (Error::LintError)

    An unexpected condition was detected, and lint mode is enabled.

Since:

  • 2.0.0



176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/mongo/server_selector/base.rb', line 176

def select_server(
  cluster,
  ping = nil,
  session = nil,
  write_aggregation: false,
  deprioritized: [],
  timeout: nil
)
  select_server_impl(cluster, ping, session, write_aggregation, deprioritized, timeout).tap do |server|
    if Lint.enabled? && !server.pool.ready?
      raise Error::LintError, 'Server selector returning a server with a pool which is not ready'
    end
  end
end

#server_selection_timeoutFloat

Deprecated.

This setting is now taken from the cluster options when a server is selected. Will be removed in version 3.0.

Get the timeout for server selection.

Examples:

Get the server selection timeout, in seconds.

selector.server_selection_timeout

Returns:

  • (Float)

    The timeout.

Since:

  • 2.0.0



83
84
85
86
# File 'lib/mongo/server_selector/base.rb', line 83

def server_selection_timeout
  @server_selection_timeout ||=
    options[:server_selection_timeout] || ServerSelector::SERVER_SELECTION_TIMEOUT
end

#suitable_servers(cluster, deprioritized = []) ⇒ Array<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.

Returns servers satisfying the server selector from the cluster.

Parameters:

  • cluster (Cluster)

    The cluster.

  • deprioritized (Array<Server>) (defaults to: [])

    A list of servers that should be selected from only if no other servers are available.

Returns:

  • (Array<Server>)

    The suitable servers.

Since:

  • 2.0.0



409
410
411
412
413
# File 'lib/mongo/server_selector/base.rb', line 409

def suitable_servers(cluster, deprioritized = [])
  result = suitable_servers_impl(cluster, deprioritized)
  result = suitable_servers_impl(cluster, []) if result.empty? && deprioritized.any?
  result
end

#try_select_server(cluster, write_aggregation: false, deprioritized: []) ⇒ Server | 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.

Tries to find a suitable server, returns the server if one is available or nil if there isn’t a suitable server.

Parameters:

  • cluster (Mongo::Cluster)

    The cluster from which to select an eligible server.

  • write_aggregation (true | false) (defaults to: false)

    Whether we need a server that supports writing aggregations (e.g. with $merge/$out) on secondaries.

  • deprioritized (Array<Server>) (defaults to: [])

    A list of servers that should be selected from only if no other servers are available. This is used to avoid selecting the same server twice in a row when retrying a command.

Returns:

  • (Server | nil)

    A suitable server, if one exists.

Since:

  • 2.0.0



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/mongo/server_selector/base.rb', line 337

def try_select_server(cluster, write_aggregation: false, deprioritized: [])
  servers = if write_aggregation && cluster.replica_set?
              # 1. Check if ALL servers in cluster support secondary writes.
              is_write_supported = cluster.servers.reduce(true) do |res, server|
                res && server.features.merge_out_on_secondary_enabled?
              end

              if is_write_supported
                # 2. If all servers support secondary writes, we respect read preference.
                suitable_servers(cluster, deprioritized)
              else
                # 3. Otherwise we fallback to primary for replica set.
                [ cluster.servers.detect(&:primary?) ]
              end
            else
              suitable_servers(cluster, deprioritized)
            end

  # This list of servers may be ordered in a specific way
  # by the selector (e.g. for secondary preferred, the first
  # server may be a secondary and the second server may be primary)
  # and we should take the first server here respecting the order
  server = suitable_server(servers)

  if server && Lint.enabled? && server.average_round_trip_time.nil?
    # It is possible for a server to have a nil average RTT here
    # because the ARTT comes from description which may be updated
    # by a background thread while server selection is running.
    # Currently lint mode is not a public feature, if/when this
    # changes (https://jira.mongodb.org/browse/RUBY-1576) the
    # requirement for ARTT to be not nil would need to be removed.
    raise Error::LintError, "Server #{server.address} has nil average rtt"
  end

  server
end