lib/mongo/retryable.rb in mongo-2.4.1 vs lib/mongo/retryable.rb in mongo-2.4.2

- old
+ new

@@ -17,20 +17,10 @@ # Defines basic behaviour around retrying operations. # # @since 2.1.0 module Retryable - # The not master error message. - # - # @since 2.1.0 - NOT_MASTER = 'not master'.freeze - - # Could not contact primary error message, seen on stepdowns - # - # @since 2.2.0 - COULD_NOT_CONTACT_PRIMARY = 'could not contact primary'.freeze - # Execute a read operation with a retry. # # @api private # # @example Execute the read. @@ -44,25 +34,26 @@ # @param [ Proc ] block The block to execute. # # @return [ Result ] The result of the operation. # # @since 2.1.0 - def read_with_retry(attempt = 0, &block) + def read_with_retry + attempt = 0 begin - block.call - rescue Error::SocketError, Error::SocketTimeoutError - retry_operation(&block) + attempt += 1 + yield + rescue Error::SocketError, Error::SocketTimeoutError => e + raise(e) if attempt > cluster.max_read_retries + log_retry(e) + cluster.scan! + retry rescue Error::OperationFailure => e if cluster.sharded? && e.retryable? - if attempt < cluster.max_read_retries - # We don't scan the cluster in this case as Mongos always returns - # ready after a ping no matter what the state behind it is. - sleep(cluster.read_retry_interval) - read_with_retry(attempt + 1, &block) - else - raise e - end + raise(e) if attempt > cluster.max_read_retries + log_retry(e) + sleep(cluster.read_retry_interval) + retry else raise e end end end @@ -81,15 +72,14 @@ # @param [ Proc ] block The block to execute. # # @return [ Result ] The result of the operation. # # @since 2.2.6 - def read_with_one_retry(&block) - block.call - rescue Error::SocketError, - Error::SocketTimeoutError - block.call + def read_with_one_retry + yield + rescue Error::SocketError, Error::SocketTimeoutError + yield end # Execute a write operation with a retry. # # @api private @@ -105,25 +95,30 @@ # @param [ Proc ] block The block to execute. # # @return [ Result ] The result of the operation. # # @since 2.1.0 - def write_with_retry(&block) + def write_with_retry + attempt = 0 begin - block.call + attempt += 1 + yield rescue Error::OperationFailure => e - if e.message.include?(NOT_MASTER) || e.message.include?(COULD_NOT_CONTACT_PRIMARY) - retry_operation(&block) + raise(e) if attempt > Cluster::MAX_WRITE_RETRIES + if e.write_retryable? + log_retry(e) + cluster.scan! + retry else - raise e + raise(e) end end end private - def retry_operation(&block) - cluster.scan! - block.call + # Log a warning so that any application slow down is immediately obvious. + def log_retry(e) + Logger.logger.warn "Retry due to: #{e.class.name} #{e.message}" end end end