SERVER-119731 Allow re-entering low priority operations in ordered queue even if maxQueueDepth is exceeded (#49077)
Co-authored-by: Pol Pinol Castuera <pol.pinol@mongodb.com> GitOrigin-RevId: ce084777b81af22b48f0e0ccb9acddd482b187c8
This commit is contained in:
committed by
MongoDB Bot
parent
64eec475c2
commit
2cc62a244f
@@ -49,7 +49,8 @@ bool OrderedTicketSemaphore::acquire(OperationContext* opCtx,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static_cast<int>(_waitQueue.size()) >= _maxWaiters.loadRelaxed()) {
|
if (admCtx->getLowAdmissions() == 0 &&
|
||||||
|
static_cast<int>(_waitQueue.size()) >= _maxWaiters.loadRelaxed()) {
|
||||||
admCtx->recordOperationLoadShed();
|
admCtx->recordOperationLoadShed();
|
||||||
lk.unlock();
|
lk.unlock();
|
||||||
uasserted(ErrorCodes::AdmissionQueueOverflow,
|
uasserted(ErrorCodes::AdmissionQueueOverflow,
|
||||||
|
|||||||
@@ -370,4 +370,42 @@ TEST_F(OrderedTicketSemaphoreTest, TryAcquireReturnsFalseWhenWaitersQueued) {
|
|||||||
future.get();
|
future.get();
|
||||||
ASSERT_EQ(sem->available(), 0);
|
ASSERT_EQ(sem->available(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that operations with lowAdmissions > 0 can bypass the max waiters limit.
|
||||||
|
*/
|
||||||
|
TEST_F(OrderedTicketSemaphoreTest, LowAdmissionsCanBypassMaxWaitersLimit) {
|
||||||
|
auto sem = makeSemaphore(0, 1); // 0 tickets, max 1 waiter.
|
||||||
|
|
||||||
|
MockAdmissionContext admCtx1, admCtx2WithLowAdmissions, admCtx3NoLowAdmissions;
|
||||||
|
|
||||||
|
auto future1 = launchAsync([&]() {
|
||||||
|
auto [client, opCtx] = makeOpCtx();
|
||||||
|
ASSERT_TRUE(sem->acquire(opCtx.get(), &admCtx1, Date_t::max(), true));
|
||||||
|
});
|
||||||
|
|
||||||
|
waitForQueuedThreads(sem, 1);
|
||||||
|
ASSERT_EQ(sem->waiters(), 1);
|
||||||
|
|
||||||
|
ASSERT_THROWS_CODE(sem->acquire(opCtx(), &admCtx3NoLowAdmissions, getDeadline(), true),
|
||||||
|
DBException,
|
||||||
|
ErrorCodes::AdmissionQueueOverflow);
|
||||||
|
ASSERT_EQ(sem->waiters(), 1); // Queue unchanged.
|
||||||
|
|
||||||
|
// An operation with lowAdmissions > 0 should be able to bypass the limit.
|
||||||
|
admCtx2WithLowAdmissions.recordLowAdmission();
|
||||||
|
ASSERT_GT(admCtx2WithLowAdmissions.getLowAdmissions(), 0);
|
||||||
|
|
||||||
|
auto future2 = launchAsync([&]() {
|
||||||
|
auto [client, opCtx] = makeOpCtx();
|
||||||
|
ASSERT_TRUE(sem->acquire(opCtx.get(), &admCtx2WithLowAdmissions, Date_t::max(), true));
|
||||||
|
});
|
||||||
|
|
||||||
|
waitForQueuedThreads(sem, 2);
|
||||||
|
ASSERT_EQ(sem->waiters(), 2);
|
||||||
|
|
||||||
|
sem->resize(2);
|
||||||
|
future1.get();
|
||||||
|
future2.get();
|
||||||
|
}
|
||||||
} // namespace mongo
|
} // namespace mongo
|
||||||
|
|||||||
Reference in New Issue
Block a user