mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 16:23:48 +00:00
Update ExceptionsOnlyLimiter.kt
This commit is contained in:
parent
91307f3ebf
commit
f686be0271
@ -26,7 +26,6 @@ import kotlinx.coroutines.sync.withLock
|
|||||||
*/
|
*/
|
||||||
class ExceptionsOnlyLimiter(
|
class ExceptionsOnlyLimiter(
|
||||||
private val defaultTooManyRequestsDelay: MilliSeconds = 1000L,
|
private val defaultTooManyRequestsDelay: MilliSeconds = 1000L,
|
||||||
private val requestKeyFactory: suspend (Request<*>) -> Any = { it::class }
|
|
||||||
) : RequestLimiter {
|
) : RequestLimiter {
|
||||||
/**
|
/**
|
||||||
* Should be used for all [mutexesMap] changes
|
* Should be used for all [mutexesMap] changes
|
||||||
@ -59,42 +58,12 @@ class ExceptionsOnlyLimiter(
|
|||||||
/**
|
/**
|
||||||
* Just call [block]
|
* Just call [block]
|
||||||
*/
|
*/
|
||||||
override suspend fun <T> limit(block: suspend () -> T): T = block()
|
override suspend fun <T> limit(block: suspend () -> T): T {
|
||||||
|
try {
|
||||||
/**
|
block()
|
||||||
* Will take a key for [request] using [requestKeyFactory] and try to retrieve [Mutex] by that key. In case if [Mutex]
|
} catch (e: TooMuchRequestsException) {
|
||||||
* presented it will wait while [Mutex] is locked. After that operations completed, method will call
|
delay(e.retryAfter.leftToRetry)
|
||||||
* [limit] with [block] inside of [safely] and in case of exception will call internal [lock] method
|
|
||||||
*/
|
|
||||||
override suspend fun <T : Any> limit(request: Request<T>, block: suspend () -> T): T {
|
|
||||||
val key = requestKeyFactory(request)
|
|
||||||
while (true) {
|
|
||||||
// do nothing, just wait for unlock in case when mutex is presented in mutexesMap
|
|
||||||
lockMutex.withLock { mutexesMap[key] } ?.takeIf { it.isLocked } ?.withLock { }
|
|
||||||
var throwable: Throwable? = null
|
|
||||||
val result = safely({
|
|
||||||
throwable = when (it) {
|
|
||||||
is TooMuchRequestsException -> {
|
|
||||||
lock(key, it.retryAfter.leftToRetry)
|
|
||||||
it
|
|
||||||
}
|
|
||||||
is ClientRequestException -> {
|
|
||||||
if (it.response.status == HttpStatusCode.TooManyRequests) {
|
|
||||||
lock(key, defaultTooManyRequestsDelay)
|
|
||||||
} else {
|
|
||||||
throw it
|
|
||||||
}
|
|
||||||
it
|
|
||||||
}
|
|
||||||
else -> throw it
|
|
||||||
}
|
|
||||||
null
|
|
||||||
}) {
|
|
||||||
limit(block)
|
limit(block)
|
||||||
}
|
}
|
||||||
if (throwable == null) {
|
|
||||||
return result!!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user