Module: Mongo::Retryable

Overview

Defines basic behaviour around retrying operations.

Since:

  • 2.1.0

Constant Summary collapse

NOT_MASTER =

The not master error message.

Since:

  • 2.1.0

'not master'.freeze
COULD_NOT_CONTACT_PRIMARY =

Could not contact primary error message, seen on stepdowns

Since:

  • 2.2.0

'could not contact primary'.freeze

Instance Method Summary collapse

Instance Method Details

#read_with_retry(attempt = 0, &block) ⇒ Result

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

This only retries read operations on socket errors.

Execute a read operation with a retry.

Examples:

Execute the read.

read_with_retry do
  ...
end

Parameters:

  • attempt (Integer) (defaults to: 0)

    The retry attempt count - for internal use.

  • block (Proc)

    The block to execute.

Returns:

  • (Result)

    The result of the operation.

Since:

  • 2.1.0



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 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

#write_with_retry(&block) ⇒ Result

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

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.

Execute a write operation with a retry.

Examples:

Execute the write.

write_with_retry do
  ...
end

Parameters:

  • block (Proc)

    The block to execute.

Returns:

  • (Result)

    The result of the operation.

Since:

  • 2.1.0



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mongo/retryable.rb', line 87

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