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