|
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.
|