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?