Skip to content

Instantly share code, notes, and snippets.

@scottashipp
Last active November 19, 2015 18:02
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 scottashipp/54daad95657c15f6d6ce to your computer and use it in GitHub Desktop.
Save scottashipp/54daad95657c15f6d6ce to your computer and use it in GitHub Desktop.
Use a LinkedBlockingQueue to limit the number of times a method executes in a sliding window of time (60 times in the past minute in this example)
import java.util.concurrent.LinkedBlockingQueue;
import org.joda.time.*;
public class LimitAccess {
final private int LIMIT = 60;
final private LinkedBlockingQueue<DateTime> accessQueue;
public LimitAccess() {
accessQueue = new LinkedBlockingQueue<>();
}
//cannot be called more than LIMIT times a minute
void myMethod() {
if(isOverLimit()) {
System.out.printf("Call disallowed. There have been more than %s calls in the past minute.%n", LIMIT);
return;
}
System.out.printf("Call allowed. This is call #%s in the last minute.%n", accessQueue.size());
}
private boolean isOverLimit() {
trimAccessQueue();
try {
accessQueue.put(DateTime.now());
} catch(InterruptedException ex) {}
return accessQueue.size() > LIMIT;
}
private void trimAccessQueue() {
final DateTime oneMinuteAgo = DateTime.now().minusMinutes(1);
while(accessQueue.size() > 0 && accessQueue.peek().isBefore(oneMinuteAgo)) {
accessQueue.poll();
}
}
private void pauseMoreThanOneSecond() {
int millisToPause = Double.valueOf(Math.random() * 1200).intValue();
try {
Thread.sleep(millisToPause);
} catch(InterruptedException ex) {}
}
public static void main(String[] args) {
LimitAccess l = new LimitAccess();
while(true) {
l.myMethod();
l.pauseMoreThanOneSecond();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment