module Mongo::Retryable

Defines basic behaviour around retrying operations.

@since 2.1.0

Public Instance Methods

read_with_one_retry() { || ... } click to toggle source

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 77
def read_with_one_retry
  yield
rescue Error::SocketError, Error::SocketTimeoutError
  yield
end
read_with_retry() { || ... } click to toggle source

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 39
def read_with_retry
  attempt = 0
  begin
    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?
      raise(e) if attempt > cluster.max_read_retries
      log_retry(e)
      sleep(cluster.read_retry_interval)
      retry
    else
      raise e
    end
  end
end
write_with_retry() { || ... } click to toggle source

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 100
def write_with_retry
  attempt = 0
  begin
    attempt += 1
    yield
  rescue Error::OperationFailure => e
    raise(e) if attempt > Cluster::MAX_WRITE_RETRIES
    if e.write_retryable?
      log_retry(e)
      cluster.scan!
      retry
    else
      raise(e)
    end
  end
end

Private Instance Methods

log_retry(e) click to toggle source

Log a warning so that any application slow down is immediately obvious.

# File lib/mongo/retryable.rb, line 120
def log_retry(e)
  Logger.logger.warn "Retry due to: #{e.class.name} #{e.message}"
end