commonMain.ratelimit.ExclusionRequestRateLimiter.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kord-rest Show documentation
Show all versions of kord-rest Show documentation
Idiomatic Kotlin Wrapper for The Discord API
The newest version!
package dev.kord.rest.ratelimit
import dev.kord.rest.request.Request
import dev.kord.rest.request.RequestIdentifier
import dev.kord.rest.request.identifier
import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.sync.Mutex
import kotlinx.datetime.Clock
private val requestLogger = KotlinLogging.logger {}
/**
* A [RequestRateLimiter] that handles all [requests][Request] in sequential order,
* minimizing the possibility of rate limits. Requests are handled in call order
* and will suspend to adhere to global and bucket rate limits.
*
* @param clock a [Clock] used for calculating suspension times, present for testing purposes.
*/
public class ExclusionRequestRateLimiter(clock: Clock = Clock.System) : AbstractRateLimiter(clock) {
override val logger: KLogger get() = requestLogger
private val sequentialLock = Mutex()
override suspend fun await(request: Request<*, *>): RequestToken {
sequentialLock.lock()
return super.await(request)
}
override fun newToken(request: Request<*, *>, buckets: List): RequestToken {
return ExclusionRequestToken(this, request.identifier, buckets)
}
private inner class ExclusionRequestToken(
rateLimiter: ExclusionRequestRateLimiter,
identity: RequestIdentifier,
requestBuckets: List
) :
AbstractRequestToken(rateLimiter, identity, requestBuckets) {
override suspend fun complete(response: RequestResponse) {
super.complete(response)
sequentialLock.unlock()
}
}
}