lib/mongo/server_selector/selectable.rb in mongo-2.12.4 vs lib/mongo/server_selector/selectable.rb in mongo-2.13.0.beta1
- old
+ new
@@ -1,6 +1,6 @@
-# Copyright (C) 2014-2019 MongoDB, Inc.
+# Copyright (C) 2014-2020 MongoDB Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
@@ -34,23 +34,29 @@
# nearest selection in seconds.
# @option options [ Integer ] max_staleness 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.
+ # @option options [ Hash | nil ] hedge 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.
#
# @raise [ Error::InvalidServerPreference ] If tag sets are specified
# but not allowed.
#
# @since 2.0.0
def initialize(options = nil)
options = options ? options.dup : {}
if options[:max_staleness] == -1
options.delete(:max_staleness)
end
- @options = options.freeze
- @tag_sets = (options[:tag_sets] || []).freeze
+ @options = options
+ @tag_sets = options[:tag_sets] || []
@max_staleness = options[:max_staleness]
+ @hedge = options[:hedge]
+
validate!
end
# @return [ Hash ] options The options.
attr_reader :options
@@ -62,10 +68,14 @@
# secondary can suffer and still be eligible for a read.
#
# @since 2.4.0
attr_reader :max_staleness
+ # @return [ Hash | nil ] hedge The document specifying whether to enable
+ # hedged reads.
+ attr_reader :hedge
+
# Check equality of two server selector.
#
# @example Check server selector equality.
# preference == other
#
@@ -73,13 +83,12 @@
#
# @return [ true, false ] Whether the objects are equal.
#
# @since 2.0.0
def ==(other)
- name == other.name &&
- tag_sets == other.tag_sets &&
- max_staleness == other.max_staleness
+ name == other.name && hedge == other.hedge &&
+ max_staleness == other.max_staleness && tag_sets == other.tag_sets
end
# Inspect the server selector.
#
# @example Inspect the server selector.
@@ -87,11 +96,11 @@
#
# @return [ String ] The inspection.
#
# @since 2.2.0
def inspect
- "#<#{self.class.name}:0x#{object_id} tag_sets=#{tag_sets.inspect} max_staleness=#{max_staleness.inspect}>"
+ "#<#{self.class.name}:0x#{object_id} tag_sets=#{tag_sets.inspect} max_staleness=#{max_staleness.inspect} hedge=#{hedge}>"
end
# Select a server from the specified cluster, taking into account
# mongos pinning for the specified session.
#
@@ -213,18 +222,10 @@
# 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 = servers.first
- if cluster.topology.single? &&
- cluster.topology.replica_set_name &&
- cluster.topology.replica_set_name != server.description.replica_set_name
- then
- msg = "Cluster topology specifies replica set name #{cluster.topology.replica_set_name}, but the server has replica set name #{server.description.replica_set_name || '<nil>'}"
- raise Error::NoServerAvailable.new(self, cluster, msg)
- end
-
if session && session.starting_transaction? && cluster.sharded?
session.pin(server)
end
return server
@@ -442,9 +443,23 @@
def validate!
if !@tag_sets.all? { |set| set.empty? } && !tags_allowed?
raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_TAG_SUPPORT)
elsif @max_staleness && !max_staleness_allowed?
raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_MAX_STALENESS_SUPPORT)
+ end
+
+ if @hedge
+ unless hedge_allowed?
+ raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_HEDGE_SUPPORT)
+ end
+
+ unless @hedge.is_a?(Hash) && @hedge.key?(:enabled) &&
+ [true, false].include?(@hedge[:enabled])
+ raise Error::InvalidServerPreference.new(
+ "`hedge` value (#{hedge}) is invalid - hedge must be a Hash in the " \
+ "format { enabled: true }"
+ )
+ end
end
end
def validate_max_staleness_support!(server)
if @max_staleness && !server.features.max_staleness_enabled?