Skip to content

Commit 9b9f76c

Browse files
erin2722MongoDB Bot
authored andcommitted
SERVER-106149 RateLimiter should return tokens to bucket upon rejection (#37246)
GitOrigin-RevId: 53e95641575e220ec4b3ea2525ec9cf9cb3f48a5
1 parent 33cac2d commit 9b9f76c

File tree

3 files changed

+301
-195
lines changed

3 files changed

+301
-195
lines changed

src/mongo/db/admission/rate_limiter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <folly/TokenBucket.h>
3333

3434
#include "mongo/logv2/log.h"
35+
#include "mongo/logv2/log_severity_suppressor.h"
3536
#include "mongo/util/duration.h"
3637
#include "mongo/util/scopeguard.h"
3738

@@ -123,6 +124,10 @@ Status RateLimiter::acquireToken(OperationContext* opCtx) {
123124
// don't advance the mock clock before the sleep deadline is calculated.
124125
Date_t deadline = opCtx->getServiceContext()->getPreciseClockSource()->now() + napTime;
125126
if (auto status = _impl->enqueue(); !status.isOK()) {
127+
{
128+
auto lk = _impl->rwMutex.readLock();
129+
_impl->tokenBucket.returnTokens(1.0);
130+
}
126131
_impl->stats.rejectedAdmissions.incrementRelaxed();
127132
return status;
128133
}
@@ -157,6 +162,7 @@ Status RateLimiter::acquireToken(OperationContext* opCtx) {
157162

158163
_impl->stats.successfulAdmissions.incrementRelaxed();
159164
_impl->stats.averageTimeQueuedMicros.addSample(waitForTokenSecs * 1'000'000);
165+
160166
return Status::OK();
161167
}
162168

@@ -206,6 +212,11 @@ double RateLimiter::tokensAvailable() const {
206212
return _impl->tokenBucket.available();
207213
}
208214

215+
double RateLimiter::tokenBalance() const {
216+
auto lk = _impl->rwMutex.readLock();
217+
return _impl->tokenBucket.balance();
218+
}
219+
209220
int64_t RateLimiter::queued() const {
210221
return _impl->queued.load();
211222
}

src/mongo/db/admission/rate_limiter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ class RateLimiter {
129129
/** Returns the number of tokens available in the underlying token bucket. **/
130130
double tokensAvailable() const;
131131

132+
/**
133+
* Returns the balance of tokens in the bucket, which may be negative if requests have
134+
* "borrowed" tokens.
135+
* */
136+
double tokenBalance() const;
137+
132138
/** Returns the number of sessions that are sleeping in acquireToken(...). **/
133139
int64_t queued() const;
134140

0 commit comments

Comments
 (0)