The following code gets a lock before collecting the slow operation statistics from the storage engine:
try {
// Retrieving storage stats should not be blocked by oplog application.
ShouldNotConflictWithSecondaryBatchApplicationBlock shouldNotConflictBlock(
opCtx->lockState());
Lock::GlobalLock lk(opCtx,
MODE_IS,
Date_t::now() + Milliseconds(500),
Lock::InterruptBehavior::kLeaveUnlocked);
if (lk.isLocked()) {
_debug.storageStats = opCtx->recoveryUnit()->getOperationStatistics();
} else {
LOGV2_WARNING_OPTIONS(
20525,
{component},
"Failed to gather storage statistics for {opId} due to {reason}",
"Failed to gather storage statistics for slow operation",
"opId"_attr = opCtx->getOpID(),
"error"_attr = "lock acquire timeout"_sd);
}
} catch (const ExceptionForCat<ErrorCategory::Interruption>& ex) {
LOGV2_WARNING_OPTIONS(
20526,
{component},
"Failed to gather storage statistics for {opId} due to {reason}",
"Failed to gather storage statistics for slow operation",
"opId"_attr = opCtx->getOpID(),
"error"_attr = redact(ex));
}
}
The interrupt behaviour for the lock is Lock::InterruptBehavior::kLeaveUnlocked, which doesn't seem to throw an exception:
/**
* The interrupt behavior is used to tell a lock how to handle an interrupted lock acquisition.
*/
enum class InterruptBehavior {
kThrow, // Throw the interruption exception.
kLeaveUnlocked // Suppress the exception, but leave unlocked such that a call to isLocked()
// returns false.
};
But in the code, we try to catch the exception of type interrupt and return a different error message than when the lock times out vs is interrupted. It is likely that the catch block is not needed and the code will never throw an exception.