lib/mongo/cluster.rb in mongo-2.13.0.beta1 vs lib/mongo/cluster.rb in mongo-2.13.0.rc1
- old
+ new
@@ -393,11 +393,11 @@
#
# @return [ Array<Server> ] The candidate servers.
#
# @since 2.0.0
def servers
- topology.servers(servers_list.compact).compact
+ topology.servers(servers_list)
end
# The addresses in the cluster.
#
# @example Get the addresses in the cluster.
@@ -597,15 +597,18 @@
# @option options [ true | false ] :keep_connection_pool Usually when the
# new server description is unknown, the connection pool on the
# respective server is cleared. Set this option to true to keep the
# existing connection pool (required when handling not master errors
# on 4.2+ servers).
+ # @option aptions [ true | false ] :awaited Whether the updated description
+ # was a result of processing an awaited ismaster.
#
# @api private
def run_sdam_flow(previous_desc, updated_desc, options = {})
@sdam_flow_lock.synchronize do
- flow = SdamFlow.new(self, previous_desc, updated_desc)
+ flow = SdamFlow.new(self, previous_desc, updated_desc,
+ awaited: options[:awaited])
flow.server_description_changed
# SDAM flow may alter the updated description - grab the final
# version for the purposes of broadcasting if a server is available
updated_desc = flow.updated_desc
@@ -884,38 +887,55 @@
Monitoring::Event::ServerClosed.new(server.address, topology)
)
end
end
- # Returns whether the deployment that the driver is connected to supports
- # sessions.
+ # Raises Error::SessionsNotAvailable if the deployment that the driver
+ # is connected to does not support sessions.
#
# Session support may change over time, for example due to servers in the
- # deployment being upgraded or downgraded. This method returns the
- # current information if the client is connected to at least one data
- # bearing server. If the client is currently not connected to any data
- # bearing servers, this method returns the last known value for whether
- # the deployment supports sessions.
+ # deployment being upgraded or downgraded. If the client is currently not
+ # connected to any data bearing servers, this method considers the state
+ # of session support as of when the client was last connected to at
+ # least one server. If the client has never connected to any servers,
+ # the deployment is considered to not support sessions.
#
- # @return [ true | false ] Whether deployment supports sessions.
# @api private
- def sessions_supported?
- if topology.data_bearing_servers?
- return !!topology.logical_session_timeout
+ def validate_session_support!
+ @state_change_lock.synchronize do
+ @sdam_flow_lock.synchronize do
+ if topology.data_bearing_servers?
+ unless topology.logical_session_timeout
+ raise_sessions_not_supported
+ end
+ end
+ end
end
# No data bearing servers known - perform server selection to try to
# get a response from at least one of them, to return an accurate
# assessment of whether sessions are currently supported.
begin
ServerSelector.get(mode: :primary_preferred).select_server(self)
- !!topology.logical_session_timeout
+ @state_change_lock.synchronize do
+ @sdam_flow_lock.synchronize do
+ unless topology.logical_session_timeout
+ raise_sessions_not_supported
+ end
+ end
+ end
rescue Error::NoServerAvailable
# We haven't been able to contact any servers - use last known
- # value for esssion support.
- @update_lock.synchronize do
- @sessions_supported || false
+ # value for session support.
+ @state_change_lock.synchronize do
+ @sdam_flow_lock.synchronize do
+ @update_lock.synchronize do
+ unless @sessions_supported
+ raise_sessions_not_supported
+ end
+ end
+ end
end
end
end
private
@@ -949,9 +969,25 @@
if @srv_monitor
@srv_monitor.stop!
end
end
end
+ end
+
+ def raise_sessions_not_supported
+ # Intentionally using @servers instead of +servers+ here because we
+ # are supposed to be already holding the @update_lock and we cannot
+ # recursively acquire it again.
+ offending_servers = @servers.select do |server|
+ server.description.data_bearing? && server.logical_session_timeout.nil?
+ end
+ reason = if offending_servers.empty?
+ "There are no known data bearing servers (current seeds: #{@servers.map(&:address).map(&:seed).join(', ')})"
+ else
+ "The following servers have null logical session timeout: #{offending_servers.map(&:address).map(&:seed).join(', ')}"
+ end
+ msg = "The deployment that the driver is connected to does not support sessions: #{reason}"
+ raise Error::SessionsNotSupported, msg
end
end
end
require 'mongo/cluster/sdam_flow'