Skip to content

Instantly share code, notes, and snippets.

@VenkataRaju
Last active April 10, 2016 11:28
Show Gist options
  • Save VenkataRaju/96524d3a4c6425c6808c2f234fc4859f to your computer and use it in GitHub Desktop.
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
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