lib/mongo/server_selector/selectable.rb in mongo-2.4.0.rc1 vs lib/mongo/server_selector/selectable.rb in mongo-2.4.0

- old
+ new

@@ -24,11 +24,11 @@ attr_reader :options # @return [ Array ] tag_sets The tag sets used to select servers. attr_reader :tag_sets - # @return [ Float ] max_staleness The maximum replication lag, in seconds, that a + # @return [ 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 attr_reader :max_staleness @@ -66,11 +66,11 @@ # # @since 2.0.0 def initialize(options = {}) @options = (options || {}).freeze @tag_sets = (options[:tag_sets] || []).freeze - @max_staleness = options[:max_staleness] if options[:max_staleness] && options[:max_staleness] > 0 + @max_staleness = options[:max_staleness] unless options[:max_staleness] == -1 validate! end # Inspect the server selector. # @@ -144,23 +144,33 @@ # Will be removed in 3.0. def local_threshold @local_threshold ||= (options[:local_threshold] || ServerSelector::LOCAL_THRESHOLD) end - private - + # Get the potential candidates to select from the cluster. + # + # @example Get the server candidates. + # selectable.candidates(cluster) + # + # @param [ Cluster ] cluster The cluster. + # + # @return [ Array<Server> ] The candidate servers. + # + # @since 2.4.0 def candidates(cluster) if cluster.single? cluster.servers.each { |server| validate_max_staleness_support!(server) } elsif cluster.sharded? near_servers(cluster.servers).each { |server| validate_max_staleness_support!(server) } else - validate_max_staleness_value!(cluster) + validate_max_staleness_value!(cluster) unless cluster.unknown? select(cluster.servers) end end + private + # Select the primary from a list of provided candidates. # # @param [ Array ] candidates List of candidate servers to select the # primary from. # @@ -198,11 +208,11 @@ # # @since 2.0.0 def near_servers(candidates = []) return candidates if candidates.empty? nearest_server = candidates.min_by(&:average_round_trip_time) - threshold = nearest_server.average_round_trip_time + (local_threshold * 1000) + threshold = nearest_server.average_round_trip_time + local_threshold candidates.select { |server| server.average_round_trip_time <= threshold }.shuffle! end # Select the servers matching the defined tag sets. # @@ -228,18 +238,18 @@ if primary candidates.select do |server| validate_max_staleness_support!(server) staleness = (server.last_scan - server.last_write_date) - (primary.last_scan - primary.last_write_date) + - (server.heartbeat_frequency * 1000) + (server.heartbeat_frequency_seconds * 1000) staleness <= max_staleness_ms end else max_write_date = candidates.collect(&:last_write_date).max candidates.select do |server| validate_max_staleness_support!(server) - staleness = max_write_date - server.last_write_date + (server.heartbeat_frequency * 1000) + staleness = max_write_date - server.last_write_date + (server.heartbeat_frequency_seconds * 1000) staleness <= max_staleness_ms end end end @@ -256,13 +266,15 @@ raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::NO_MAX_STALENESS_WITH_LEGACY_SERVER) end end def validate_max_staleness_value!(cluster) - return unless @max_staleness - heartbeat_frequency = cluster.options[:heartbeat_frequency] || Server::Monitor::HEARTBEAT_FREQUENCY - if @max_staleness < heartbeat_frequency * 2 - raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::INVALID_MAX_STALENESS) + if @max_staleness + heartbeat_frequency_seconds = cluster.options[:heartbeat_frequency] || Server::Monitor::HEARTBEAT_FREQUENCY + unless @max_staleness >= [ SMALLEST_MAX_STALENESS_SECONDS, + (heartbeat_frequency_seconds + Cluster::IDLE_WRITE_PERIOD_SECONDS) ].max + raise Error::InvalidServerPreference.new(Error::InvalidServerPreference::INVALID_MAX_STALENESS) + end end end end end end