jstests/libs/override_methods/network_error_and_txn_override.js
// This function is the heart of the override with the main error retry loop.
This function is the heart of the override with the main error retry loop.
This function is the heart of the override with the main error retry loop .
function runCommandOverrideBody(conn, dbName, cmdName, cmdObj, lsid, clientFunction, makeFuncArgs) {
    const startTime = Date.now();
    const isTxnStatement = isCmdInTransaction(cmdObj);
    if (configuredForNetworkRetry() && !isNested() && !isTxnStatement) {
        validateCmdNetworkErrorCompatibility(cmdName, cmdObj);
    }
    if (configuredForTxnOverride()) {
        setupTransactionCommand(conn, dbName, cmdName, cmdObj, lsid);
    }
    const canRetryNetworkError = canRetryNetworkErrorForCommand(cmdName, cmdObj);
    const canRetryReadError = canRetryReadErrorDuringBackgroundReconfig(cmdName);
    let numNetworkErrorRetries = canRetryNetworkError ? kMaxNumRetries : 0;
    do {
        try {
            let res = clientFunction.apply(conn, makeFuncArgs(cmdObj));
            if (configuredForTxnOverride()) {
                logMsgFull("Override got response",
                           `res: ${tojsononeline(res)}, cmd: ${tojsononeline(cmdObj)}`);
                if (!hasError(res) &&
                    TransactionsUtil.commandIsNonTxnAggregation(cmdName, cmdObj)) {
                    nonTxnAggCursorSet[res.cursor.id] = true;
                }
            }
            const logError = (msg) => logErrorFull(msg, cmdName, cmdObj, res);
            if (configuredForTxnOverride()) {
                res = retryWithTxnOverride(res, conn, dbName, cmdName, cmdObj, lsid, logError);
            }
            if (canRetryNetworkError) {
                const networkRetryRes = shouldRetryWithNetworkErrorOverride(res, cmdName, logError);
                if (networkRetryRes === kContinue) {
                    continue;
                } else {
                    res = networkRetryRes;
                }
            }
            if (canRetryReadError) {
                const readRetryRes =
                    shouldRetryForBackgroundReconfigOverride(res, cmdName, logError);
                if (readRetryRes === kContinue) {
                    continue;
                } else {
                    res = readRetryRes;
                }
            }
            return res;
        } catch (e) {
            const logError = (msg) => logErrorFull(msg, cmdName, cmdObj, e);
            if (configuredForTxnOverride()) {
                const txnRetryOnException =
                    retryWithTxnOverrideException(e, conn, cmdName, cmdObj, lsid, logError);
                if (txnRetryOnException) {
                    return txnRetryOnException;
                }
            }
            if (canRetryNetworkError) {
                const decrementRetryCount = shouldRetryWithNetworkExceptionOverride(
                    e, cmdName, cmdObj, startTime, numNetworkErrorRetries, logError);
                if (decrementRetryCount) {
                    --numNetworkErrorRetries;
                    logMsgFull("Decrementing command network error retry count",
                               `New count: ${numNetworkErrorRetries}`);
                }
                logErrorFull("Retrying on network error for command", cmdName, cmdObj, e);
                inCommandNetworkErrorRetry = true;
                continue;
            }
            throw e;
        }
    } while (numNetworkErrorRetries >= 0);
    throw new Error("MONGO UNREACHABLE");
}
function runCommandOverrideBody ( conn , dbName , cmdName , cmdObj , lsid , clientFunction , makeFuncArgs ) { const startTime = Date . now ( ) ; const isTxnStatement = isCmdInTransaction ( cmdObj ) ; if ( configuredForNetworkRetry ( ) && ! isNested ( ) && ! isTxnStatement ) { validateCmdNetworkErrorCompatibility ( cmdName , cmdObj ) ; } if ( configuredForTxnOverride ( ) ) { setupTransactionCommand ( conn , dbName , cmdName , cmdObj , lsid ) ; } const canRetryNetworkError = canRetryNetworkErrorForCommand ( cmdName , cmdObj ) ; const canRetryReadError = canRetryReadErrorDuringBackgroundReconfig ( cmdName ) ; let numNetworkErrorRetries = canRetryNetworkError ? kMaxNumRetries : 0 ; do { try { let res = clientFunction . apply ( conn , makeFuncArgs ( cmdObj ) ) ; if ( configuredForTxnOverride ( ) ) { logMsgFull ( "Override got response" , ` ${ tojsononeline ( res ) } ${ tojsononeline ( cmdObj ) } ` ) ; if ( ! hasError ( res ) && TransactionsUtil . commandIsNonTxnAggregation ( cmdName , cmdObj ) ) { nonTxnAggCursorSet [ res . cursor . id ] = true ; } } const logError = ( msg ) => logErrorFull ( msg , cmdName , cmdObj , res ) ; if ( configuredForTxnOverride ( ) ) { res = retryWithTxnOverride ( res , conn , dbName , cmdName , cmdObj , lsid , logError ) ; } if ( canRetryNetworkError ) { const networkRetryRes = shouldRetryWithNetworkErrorOverride ( res , cmdName , logError ) ; if ( networkRetryRes === kContinue ) { continue ; } else { res = networkRetryRes ; } } if ( canRetryReadError ) { const readRetryRes = shouldRetryForBackgroundReconfigOverride ( res , cmdName , logError ) ; if ( readRetryRes === kContinue ) { continue ; } else { res = readRetryRes ; } } return res ; } catch ( e ) { const logError = ( msg ) => logErrorFull ( msg , cmdName , cmdObj , e ) ; if ( configuredForTxnOverride ( ) ) { const txnRetryOnException = retryWithTxnOverrideException ( e , conn , cmdName , cmdObj , lsid , logError ) ; if ( txnRetryOnException ) { return txnRetryOnException ; } } if ( canRetryNetworkError ) { const decrementRetryCount = shouldRetryWithNetworkExceptionOverride ( e , cmdName , cmdObj , startTime , numNetworkErrorRetries , logError ) ; if ( decrementRetryCount ) { -- numNetworkErrorRetries ; logMsgFull ( "Decrementing command network error retry count" , ` ${ numNetworkErrorRetries } ` ) ; } logErrorFull ( "Retrying on network error for command" , cmdName , cmdObj , e ) ; inCommandNetworkErrorRetry = true ; continue ; } throw e ; } } while ( numNetworkErrorRetries >= 0 ) ; throw new Error ( "MONGO UNREACHABLE" ) ; }
This function is the heart of the override with the main error retry loop.
This function is the heart of the override with the main error retry loop .
// If this is a top level command, make sure that the command supports network error // retries. Don't validate transaction statements because their encompassing transaction // can be retried at a higher level, even if each statement isn't retryable on its own. // Actually run the provided command.