RateLimitInterceptor: ignore canceled calls (#7389)

* RateLimitInterceptor: ignore canceled calls

* SpecificHostRateLimit: ignore canceled calls

(cherry picked from commit 5b8cd68cf3)
This commit is contained in:
stevenyomi 2022-06-27 09:35:35 +08:00 committed by arkon
parent 17899a6d6d
commit 33500e5b69
2 changed files with 22 additions and 1 deletions

View file

@ -4,6 +4,7 @@ import android.os.SystemClock
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response import okhttp3.Response
import java.io.IOException
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/** /**
@ -36,6 +37,11 @@ private class RateLimitInterceptor(
private val rateLimitMillis = unit.toMillis(period) private val rateLimitMillis = unit.toMillis(period)
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
// Ignore canceled calls, otherwise they would jam the queue
if (chain.call().isCanceled()) {
throw IOException()
}
synchronized(requestQueue) { synchronized(requestQueue) {
val now = SystemClock.elapsedRealtime() val now = SystemClock.elapsedRealtime()
val waitTime = if (requestQueue.size < permits) { val waitTime = if (requestQueue.size < permits) {
@ -51,6 +57,11 @@ private class RateLimitInterceptor(
} }
} }
// Final check
if (chain.call().isCanceled()) {
throw IOException()
}
if (requestQueue.size == permits) { if (requestQueue.size == permits) {
requestQueue.removeAt(0) requestQueue.removeAt(0)
} }

View file

@ -5,6 +5,7 @@ import okhttp3.HttpUrl
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Response import okhttp3.Response
import java.io.IOException
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
/** /**
@ -41,9 +42,13 @@ class SpecificHostRateLimitInterceptor(
private val host = httpUrl.host private val host = httpUrl.host
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
if (chain.request().url.host != host) { // Ignore canceled calls, otherwise they would jam the queue
if (chain.call().isCanceled()) {
throw IOException()
} else if (chain.request().url.host != host) {
return chain.proceed(chain.request()) return chain.proceed(chain.request())
} }
synchronized(requestQueue) { synchronized(requestQueue) {
val now = SystemClock.elapsedRealtime() val now = SystemClock.elapsedRealtime()
val waitTime = if (requestQueue.size < permits) { val waitTime = if (requestQueue.size < permits) {
@ -59,6 +64,11 @@ class SpecificHostRateLimitInterceptor(
} }
} }
// Final check
if (chain.call().isCanceled()) {
throw IOException()
}
if (requestQueue.size == permits) { if (requestQueue.size == permits) {
requestQueue.removeAt(0) requestQueue.removeAt(0)
} }