Module: Mongo::Retryable
- Included in:
- BulkWrite, Cluster::CursorReaper, Collection, Collection::View, Collection::View::Aggregation, Collection::View::MapReduce, Cursor, Server::Connection, Server::Monitor::Connection, Session
- Defined in:
- lib/mongo/retryable.rb
Overview
Defines basic behavior around retrying operations.
Instance Method Summary collapse
-
#read_with_one_retry ⇒ Result
private
Execute a read operation with a single retry.
-
#read_with_retry(session = nil) ⇒ Result
private
Execute a read operation with a retry.
-
#write_with_retry(session, write_concern, ending_transaction = false, &block) {|server, txn_num| ... } ⇒ Result
private
Implements write retrying functionality by yielding to the passed block one or more times.
Instance Method Details
#read_with_one_retry ⇒ 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.
This only retries read operations on socket errors.
Execute a read operation with a single retry.
77 78 79 80 81 |
# File 'lib/mongo/retryable.rb', line 77 def read_with_one_retry yield rescue Error::SocketError, Error::SocketTimeoutError yield end |
#read_with_retry(session = nil) ⇒ 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.
This only retries read operations on socket errors.
Execute a read operation with a retry.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/mongo/retryable.rb', line 39 def read_with_retry(session = nil) attempt = 0 begin attempt += 1 yield rescue Error::SocketError, Error::SocketTimeoutError => e raise(e) if attempt > cluster.max_read_retries || (session && session.in_transaction?) log_retry(e) cluster.scan!(false) retry rescue Error::OperationFailure => e if cluster.sharded? && e.retryable? && !(session && session.in_transaction?) 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(session, write_concern, ending_transaction = false, &block) {|server, txn_num| ... } ⇒ 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.
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.
Implements write retrying functionality by yielding to the passed block one or more times.
If the session is provided (hence, the deployment supports sessions), and modern retry writes are enabled on the client, the modern retry logic is invoked. Otherwise the legacy retry logic is invoked.
If ending_transaction parameter is true, indicating that a transaction is being committed or aborted, the operation is executed exactly once. Note that, since transactions require sessions, this method will raise ArgumentError if ending_transaction is true and session is nil.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/mongo/retryable.rb', line 116 def write_with_retry(session, write_concern, ending_transaction = false, &block) if ending_transaction && !session raise ArgumentError, 'Cannot end a transaction without a session' end unless ending_transaction || retry_write_allowed?(session, write_concern) return legacy_write_with_retry(nil, session, &block) end server = cluster.next_primary unless ending_transaction || server.retry_writes? return legacy_write_with_retry(server, session, &block) end begin txn_num = session.in_transaction? ? session.txn_num : session.next_txn_num yield(server, txn_num) rescue Error::SocketError, Error::SocketTimeoutError => e raise e if session.in_transaction? && !ending_transaction retry_write(e, txn_num, &block) rescue Error::OperationFailure => e raise e if (session.in_transaction? && !ending_transaction) || !e.write_retryable? retry_write(e, txn_num, &block) end end |