From 40503b6bd288ecdf2ad33273f9c4bd8f9cf1b99c Mon Sep 17 00:00:00 2001 From: johan12345 Date: Sun, 20 Sep 2020 23:02:23 +0200 Subject: [PATCH] handle rate limiting by NewMotion API --- app/build.gradle | 1 + .../evmap/api/RateLimitInterceptor.kt | 33 +++++++++++++++++++ .../api/availability/AvailabilityDetector.kt | 2 ++ 3 files changed, 36 insertions(+) create mode 100644 app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt diff --git a/app/build.gradle b/app/build.gradle index 87c7d28b..48d12fe9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -116,6 +116,7 @@ dependencies { implementation 'com.airbnb.android:lottie:3.4.0' implementation 'io.michaelrocks:bimap:1.0.2' implementation 'com.mapzen.android:lost:3.0.2' + implementation 'com.google.guava:guava:29.0-android' // AnyMaps def anyMapsVersion = '894f6d62ac' diff --git a/app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt b/app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt new file mode 100644 index 00000000..9f593a98 --- /dev/null +++ b/app/src/main/java/net/vonforst/evmap/api/RateLimitInterceptor.kt @@ -0,0 +1,33 @@ +package net.vonforst.evmap.api + +import com.google.common.util.concurrent.RateLimiter +import okhttp3.Interceptor +import okhttp3.Response + + +class RateLimitInterceptor : Interceptor { + private val rateLimiter = RateLimiter.create(3.0) + + override fun intercept(chain: Interceptor.Chain): Response { + val request = chain.request() + if (request.url.host == "my.newmotion.com") { + // limit requests sent to NewMotion to 3 per second + rateLimiter.acquire(1) + + var response: Response = chain.proceed(request) + // 403 is how the NewMotion API indicates a rate limit error + if (!response.isSuccessful && response.code == 403) { + response.close() + // wait & retry + try { + Thread.sleep(1000) + } catch (e: InterruptedException) { + } + response = chain.proceed(request) + } + return response + } else { + return chain.proceed(request) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt b/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt index a61cb1d3..b09da549 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt @@ -3,6 +3,7 @@ package net.vonforst.evmap.api.availability import com.facebook.stetho.okhttp3.StethoInterceptor import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import net.vonforst.evmap.api.RateLimitInterceptor import net.vonforst.evmap.api.await import net.vonforst.evmap.api.goingelectric.ChargeLocation import net.vonforst.evmap.api.goingelectric.Chargepoint @@ -123,6 +124,7 @@ private val cookieManager = CookieManager().apply { } private val okhttp = OkHttpClient.Builder() + .addInterceptor(RateLimitInterceptor()) .addNetworkInterceptor(StethoInterceptor()) .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS)