1
0
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:
InsanusMokrassar 2022-12-27 22:22:03 +06:00 committed by GitHub
parent 91307f3ebf
commit f686be0271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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 limit(block)
*/
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)
}
if (throwable == null) {
return result!!
}
} }
} }
} }