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, false)
rescue Error::SocketError, Error::SocketTimeoutError => e
if session.in_transaction? && !ending_transaction
raise
end
retry_write(e, txn_num, &block)
rescue Error::OperationFailure => e
if (session.in_transaction? && !ending_transaction) || !e.write_retryable?
raise
end
retry_write(e, txn_num, &block)
end
end