Skip to content

Commit 86531b3

Browse files
Merge pull request #6961 from rust-lang/refill-rate-fix
2 parents 89e867f + a3da224 commit 86531b3

File tree

1 file changed

+71
-3
lines changed

1 file changed

+71
-3
lines changed

src/rate_limiter.rs

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ pg_enum! {
2020
impl LimitedAction {
2121
pub fn default_rate_seconds(&self) -> u64 {
2222
match self {
23-
LimitedAction::PublishNew => 60 * 60,
24-
LimitedAction::PublishUpdate => 60,
25-
LimitedAction::YankUnyank => 60,
23+
LimitedAction::PublishNew => 10 * 60, // 10 minutes
24+
LimitedAction::PublishUpdate => 60, // 1 minute
25+
LimitedAction::YankUnyank => 60, // 1 minute
2626
}
2727
}
2828

@@ -176,6 +176,74 @@ mod tests {
176176
use crate::email::Emails;
177177
use crate::test_util::*;
178178

179+
#[test]
180+
fn default_rate_limits() -> QueryResult<()> {
181+
let conn = &mut pg_connection();
182+
let now = now();
183+
184+
// Set the defaults as if no env vars have been set in production
185+
let mut rate_limiter = HashMap::new();
186+
for action in LimitedAction::VARIANTS {
187+
rate_limiter.insert(
188+
*action,
189+
RateLimiterConfig {
190+
rate: Duration::from_secs(action.default_rate_seconds()),
191+
burst: action.default_burst(),
192+
},
193+
);
194+
}
195+
let rate = RateLimiter::new(rate_limiter);
196+
197+
let user_id = new_user_bucket(conn, 5, now)?.user_id;
198+
199+
// Publishing new crates has a burst of 5 and refill time of 1 every 10 minutes, which
200+
// means we should be able to publish every 10 min, always have tokens remaining, and
201+
// set the last_refill based on the refill time.
202+
let action = LimitedAction::PublishNew;
203+
let mut last_refill_times = vec![];
204+
let mut expected_last_refill_times = vec![];
205+
for publish_num in 1..=10 {
206+
let publish_time = now + chrono::Duration::minutes(10 * publish_num);
207+
let bucket = rate.take_token(user_id, action, publish_time, conn)?;
208+
209+
last_refill_times.push(bucket.last_refill);
210+
expected_last_refill_times.push(publish_time);
211+
}
212+
assert_eq!(expected_last_refill_times, last_refill_times);
213+
214+
// Publishing new versions has a burst of 30 and refill time of every minute, which
215+
// means we should be able to publish every min, always have tokens remaining, and
216+
// set the last_refill based on the refill time.
217+
let action = LimitedAction::PublishUpdate;
218+
let mut last_refill_times = vec![];
219+
let mut expected_last_refill_times = vec![];
220+
for publish_num in 1..=35 {
221+
let publish_time = now + chrono::Duration::minutes(publish_num);
222+
let bucket = rate.take_token(user_id, action, publish_time, conn)?;
223+
224+
last_refill_times.push(bucket.last_refill);
225+
expected_last_refill_times.push(publish_time);
226+
}
227+
assert_eq!(expected_last_refill_times, last_refill_times);
228+
229+
// Yanking/unyanking has a burst of 100 and refill time of every minute, which
230+
// means we should be able to yank/unyank every min, always have tokens remaining, and
231+
// set the last_refill based on the refill time.
232+
let action = LimitedAction::YankUnyank;
233+
let mut last_refill_times = vec![];
234+
let mut expected_last_refill_times = vec![];
235+
for publish_num in 1..=110 {
236+
let publish_time = now + chrono::Duration::minutes(publish_num);
237+
let bucket = rate.take_token(user_id, action, publish_time, conn)?;
238+
239+
last_refill_times.push(bucket.last_refill);
240+
expected_last_refill_times.push(publish_time);
241+
}
242+
assert_eq!(expected_last_refill_times, last_refill_times);
243+
244+
Ok(())
245+
}
246+
179247
#[test]
180248
fn take_token_with_no_bucket_creates_new_one() -> QueryResult<()> {
181249
let conn = &mut pg_connection();

0 commit comments

Comments
 (0)