def read_with_retry(session = nil, server_selector = nil, &block)
      if session.nil? && server_selector.nil?
        # Older versions of Mongoid call read_with_retry without arguments.
        # This is already not correct in a MongoDB 3.6+ environment with
        # sessions. For compatibility we emulate the legacy driver behavior
        # here but upgrading Mongoid is strongly recommended.
        unless $_mongo_read_with_retry_warned
          $_mongo_read_with_retry_warned = true
          Logger.logger.warn("Legacy read_with_retry invocation - please update the application and/or its dependencies")
        end
        # Since we don't have a session, we cannot use the modern read retries.
        # And we need to select a server but we don't have a server selector.
        # Use PrimaryPreferred which will work as long as there is a data
        # bearing node in the cluster; the block may select a different server
        # which is fine.
        server_selector = ServerSelector.get(mode: :primary_preferred)
        legacy_read_with_retry(nil, server_selector, &block)
      elsif session && session.retry_reads?
        modern_read_with_retry(session, server_selector, &block)
      elsif client.max_read_retries > 0
        legacy_read_with_retry(session, server_selector, &block)
      else
        server = select_server(cluster, server_selector)
        yield server
      end
    end
def read_with_retry(session = nil, server_selector = nil, &block)
      if session.nil? && server_selector.nil?
        # Older versions of Mongoid call read_with_retry without arguments.
        # This is already not correct in a MongoDB 3.6+ environment with
        # sessions. For compatibility we emulate the legacy driver behavior
        # here but upgrading Mongoid is strongly recommended.
        unless $_mongo_read_with_retry_warned
          $_mongo_read_with_retry_warned = true
          Logger.logger.warn("Legacy read_with_retry invocation - please update the application and/or its dependencies")
        end
        # Since we don't have a session, we cannot use the modern read retries.
        # And we need to select a server but we don't have a server selector.
        # Use PrimaryPreferred which will work as long as there is a data
        # bearing node in the cluster; the block may select a different server
        # which is fine.
        server_selector = ServerSelector.get(mode: :primary_preferred)
        legacy_read_with_retry(nil, server_selector, &block)
      elsif session && session.retry_reads?
        modern_read_with_retry(session, server_selector, &block)
      elsif client.max_read_retries > 0
        legacy_read_with_retry(session, server_selector, &block)
      else
        server = select_server(cluster, server_selector)
        yield server
      end
    end
Execute a read operation with retrying.

 This method performs server selection for the specified server selector
 and yields to the provided block, which should execute the initial
 query operation and return its result. The block will be passed the
 server selected for the operation. If the block raises an exception,
 and this exception corresponds to a read retryable error, and read
 retries are enabled for the client, this method will perform server
 selection again and yield to the block again (with potentially a
 different server). If the block returns successfully, the result
 of the block is returned.

 If modern retry reads are on (which is the default), the initial read
 operation will be retried once. If legacy retry reads are on, the
 initial read operation will be retried zero or more times depending
 on the :max_read_retries client setting, the default for which is 1.
 To disable read retries, turn off modern read retries by setting
 retry_reads: false and set :max_read_retries to 0 on the client.

 @api private

 @example Execute the read.
   read_with_retry(session, server_selector) do |server|
     ...
   end

 @param [ Mongo::Session ] session The session that the operation is being
   run on.
 @param [ Mongo::ServerSelector::Selectable ] server_selector Server
   selector for the operation.
 @param [ Proc ] block The block to execute.

 @return [ Result ] The result of the operation.