module Mongo::Retryable
Defines basic behaviour around retrying operations.
@since 2.1.0
Constants
- COULD_NOT_CONTACT_PRIMARY
Could not contact primary error message, seen on stepdowns
@since 2.2.0
- NOT_MASTER
The not master error message.
@since 2.1.0
Public Instance Methods
Execute a read operation with a single retry.
@api private
@example Execute the read.
read_with_one_retry do ... end
@note This only retries read operations on socket errors.
@param [ Proc ] block The block to execute.
@return [ Result ] The result of the operation.
@since 2.2.6
# File lib/mongo/retryable.rb, line 86 def read_with_one_retry(&block) block.call rescue Error::SocketError, Error::SocketTimeoutError block.call end
Execute a read operation with a retry.
@api private
@example Execute the read.
read_with_retry do ... end
@note This only retries read operations on socket errors.
@param [ Integer ] attempt The retry attempt count - for internal use. @param [ Proc ] block The block to execute.
@return [ Result ] The result of the operation.
@since 2.1.0
# File lib/mongo/retryable.rb, line 49 def read_with_retry(attempt = 0, &block) begin block.call rescue Error::SocketError, Error::SocketTimeoutError retry_operation(&block) 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 else raise e end end end
Execute a write operation with a retry.
@api private
@example Execute the write.
write_with_retry do ... end
@note This only retries operations on not master failures, since it is
the only case we can be sure a partial write did not already occur.
@param [ Proc ] block The block to execute.
@return [ Result ] The result of the operation.
@since 2.1.0
# File lib/mongo/retryable.rb, line 110 def write_with_retry(&block) begin block.call rescue Error::OperationFailure => e if e.message.include?(NOT_MASTER) || e.message.include?(COULD_NOT_CONTACT_PRIMARY) retry_operation(&block) else raise e end end end
Private Instance Methods
# File lib/mongo/retryable.rb, line 124 def retry_operation(&block) cluster.scan! block.call end