Created
January 25, 2014 12:28
-
-
Save rndstr/8615632 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.util.Log; | |
import java.util.Arrays; | |
/** | |
* Sample usage: | |
* | |
* class MyApp extends Application { | |
* private Api sApi; | |
* private RequestLimiter sRequestlimiter = new RequestLimiter(5, 1000); | |
* | |
* public static synchronized Api api() { | |
* if (sApi == null) { | |
* sApi = new Api(); | |
* } | |
* | |
* sRequestLimiter.nextRequest(); | |
* return sApi; | |
* } | |
* | |
* public static Api apiWithoutRequest() { | |
* return sApi; | |
* } | |
* } | |
* | |
* @author Roland Schilter <roli@schilter.me> | |
*/ | |
public class RequestLimiter { | |
protected int mRateLimitCount; | |
protected int mRateLimitMillis; | |
protected long[] mRequestTimes; | |
/** | |
* Index of last recorded time | |
*/ | |
protected int mRequestIndex = 0; | |
protected long mRequestCount = 0; | |
/** | |
* @param rateLimitCount How many requests | |
* @param rateLimitMillis In how much time | |
*/ | |
public RequestLimiter(int rateLimitCount, int rateLimitMillis) { | |
mRateLimitCount = rateLimitCount; | |
mRateLimitMillis = rateLimitMillis; | |
mRequestTimes = new long[rateLimitCount]; | |
Arrays.fill(mRequestTimes, 0); | |
} | |
/** | |
* In case of limit exceedance we wait the required time and then record this request | |
*/ | |
public void nextRequest() { | |
waitRequest(); | |
recordRequest(); | |
} | |
protected void recordRequest() { | |
mRequestIndex = (mRequestIndex + 1) % mRateLimitCount; | |
mRequestTimes[mRequestIndex] = System.currentTimeMillis(); | |
mRequestCount += 1; | |
} | |
protected void waitRequest() { | |
// verify that time since oldest request is more than rateLimitSeconds | |
int oldestIndex = (mRequestIndex + 1) % mRateLimitCount; | |
long sinceOldestRequest = System.currentTimeMillis() - mRequestTimes[oldestIndex]; | |
// if time since oldest request (keeping only track of rate limited count times) is longer than | |
// the rate limit then we exceeded it | |
if (sinceOldestRequest < mRateLimitMillis) { | |
long pause = mRateLimitMillis - sinceOldestRequest; | |
Log.i(getClass().getName(), "Rate limit exceeded, pausing for " + pause + "ms"); | |
if (pause > mRateLimitMillis) { | |
// somebody must have been screwing with the date/time on the phone | |
// just wait the max time and reset times | |
Arrays.fill(mRequestTimes, 0); | |
pause = mRateLimitMillis; | |
} | |
try { | |
Thread.sleep(pause); | |
} catch (InterruptedException ex) { | |
Thread.currentThread().interrupt(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment