Last active
April 10, 2016 11:28
-
-
Save VenkataRaju/96524d3a4c6425c6808c2f234fc4859f to your computer and use it in GitHub Desktop.
Releases only provided number of tokens per provided timeunit, otherwise forces the caller to wait until the next set of tokens available
This file contains hidden or 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
class RateLimiter(val time: Long, val timeUnit: TimeUnit, val noOfTokensPerSlot: Int) | |
{ | |
private val timeInMillis = timeUnit.toMillis(time) | |
private var tokensReleasedTime = (System.currentTimeMillis() / 1000) * 1000 | |
private var availableTokens = noOfTokensPerSlot | |
init | |
{ | |
require(time > 0, { "time[$time] should be positive" }) | |
require(noOfTokensPerSlot > 0, { "noOfTokens[$noOfTokensPerSlot] should be positive" }) | |
} | |
fun acquireSome(noOfTokensRequired: Int = 1): Int = acquire(noOfTokensRequired, false) | |
fun acquireAll(noOfTokensRequired: Int = 1) = acquire(noOfTokensRequired, true) | |
private fun acquire(noOfTokens: Int, acquireAll: Boolean): Int | |
{ | |
require(noOfTokens in 0..noOfTokensPerSlot) | |
val nextTokensReleaseTime = tokensReleasedTime + timeInMillis; | |
val currentTime = System.currentTimeMillis() | |
if (nextTokensReleaseTime <= currentTime) | |
{ | |
tokensReleasedTime += ((currentTime - tokensReleasedTime) / timeInMillis) * timeInMillis | |
availableTokens = noOfTokensPerSlot - noOfTokens | |
} else if (noOfTokens <= availableTokens) | |
{ | |
availableTokens -= noOfTokens | |
} else if (acquireAll || availableTokens == 0) | |
{ | |
Thread.sleep(nextTokensReleaseTime - currentTime); | |
tokensReleasedTime = nextTokensReleaseTime | |
availableTokens = noOfTokensPerSlot - noOfTokens | |
} else | |
{ | |
val fewAvailableTokens = availableTokens | |
availableTokens = 0 | |
return fewAvailableTokens | |
} | |
return noOfTokens | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment