Skip to content

Instantly share code, notes, and snippets.

@evanhalley
Created December 12, 2022 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evanhalley/641d3c7f4d95bd5e413f59a6b68a84ff to your computer and use it in GitHub Desktop.
Save evanhalley/641d3c7f4d95bd5e413f59a6b68a84ff to your computer and use it in GitHub Desktop.
Naive Leaky Bucket Algorithm Implementation
import java.util.LinkedList;
import java.util.stream.Stream;
class Scratch {
public static void main(String[] args) throws InterruptedException {
int rate = Integer.parseInt(args[0]);
int maxBucketSize = Integer.parseInt(args[1]);
LinkedList<Integer> requestStream = new LinkedList<>(Stream.of(args[2].split(","))
.map(Integer::parseInt)
.toList());
LeakyBucketRateLimiter rateLimiter = new LeakyBucketRateLimiter(rate, maxBucketSize);
int numRequests = 0;
int numRequestsRateLimited = 0;
int numRequestProcessed = 0;
do {
System.out.println(rateLimiter);
if (requestStream.peek() != null) {
int requests = requestStream.pop();
numRequests += requests;
for (int i = 0; i < requests; i++) {
if (rateLimiter.putRequest()) {
System.out.println("Requests sent");
} else {
System.out.println("Request rate limited");
numRequestsRateLimited++;
}
}
}
numRequestProcessed += rateLimiter.getRequest();
// pretend some work is done
Thread.sleep(500);
} while (rateLimiter.hasRequests() || !requestStream.isEmpty());
System.out.printf("\nSummary\nTotal requests: %s, Rate Limited: %s, Processed: %s%n",
numRequests, numRequestsRateLimited, numRequestProcessed);
}
public static class LeakyBucketRateLimiter {
final int rate;
final int maxBucketSize;
int currentBucketSize;
public LeakyBucketRateLimiter(int rate, int maxBucketSize) {
this.rate = rate;
this.maxBucketSize = maxBucketSize;
this.currentBucketSize = 0;
}
public int getRequest() {
int val = 0;
if (currentBucketSize > 0) {
val = Math.min(rate, currentBucketSize);
currentBucketSize -= val;
}
return val;
}
public boolean putRequest() {
if (currentBucketSize == maxBucketSize) {
return false;
}
currentBucketSize++;
return true;
}
public boolean hasRequests() {
return currentBucketSize > 0;
}
@Override
public String toString() {
return "LeakyBucketRateLimiter{" +
"rate=" + rate +
", currentBucketSize=" + currentBucketSize +
", maxBucketSize=" + maxBucketSize +
'}';
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment