Skip to content

MrSnou/RateLimiterExercise

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Rate Limiter — concurrency exercise

Four implementations of a request counter, written to compare how they behave under concurrent access. A learning project, not a library.

The progression

Implementation Mechanism Result
NaiveRateLimiter plain int, check-then-act broken — lost updates, no visibility guarantee
SynchronizedRateLimiter monitor on the method correct, but blocking (threads park in BLOCKED)
AtomicRateLimiter AtomicInteger + CAS retry loop correct and lock-free
PerUserRateLimiter ConcurrentHashMap<String, AtomicInteger> contention split per user

Tests

RateLimiterConcurrencyTest fires N tasks through a CountDownLatch start gate so they hit the limiter simultaneously, then reports how many permits were granted.

Two tests matter most:

  • Naive over-allow — repeats the scenario 20 times and reports in how many runs the race actually materialised. Same code, different outcome per run: a green test does not mean correct code.
  • Zero surplus (100 threads, limit 100) — every rejection is a lost permit. A CAS loop that gives up after one failed attempt passes the 200-thread test and fails this one. The surplus test masks the bug.
mvn test

Known limitation

There is no time window — the counter never resets, so this limits a total quota, not a rate. A real rate limiter needs a token bucket, leaky bucket, or sliding window.

About

Four rate limiter implementations comparing check-then-act, mutual exclusion and lock-free CAS under concurrent load.

Topics

Resources

Stars

Watchers

Forks

Contributors

Languages