generated from leanix/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CID-3277: Add rate limit handling for manifest file searching
- Loading branch information
1 parent
9dd45ea
commit a109679
Showing
7 changed files
with
136 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
src/main/kotlin/net/leanix/githubagent/config/FeignClientConfig.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package net.leanix.githubagent.config | ||
|
||
import feign.ResponseInterceptor | ||
import net.leanix.githubagent.interceptor.RateLimitResponseInterceptor | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Configuration | ||
|
||
@Configuration | ||
class FeignClientConfig { | ||
|
||
@Bean | ||
fun rateLimitResponseInterceptor(): ResponseInterceptor { | ||
return RateLimitResponseInterceptor() | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/kotlin/net/leanix/githubagent/handler/RateLimitHandler.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package net.leanix.githubagent.handler | ||
|
||
import net.leanix.githubagent.services.SyncLogService | ||
import net.leanix.githubagent.shared.RateLimitMonitor | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
class RateLimitHandler( | ||
private val syncLogService: SyncLogService, | ||
) { | ||
|
||
fun <T> executeWithRateLimitHandler(block: () -> T): T { | ||
while (true) { | ||
val waitTimeSeconds = RateLimitMonitor.shouldThrottle() | ||
if (waitTimeSeconds > 0) { | ||
syncLogService.sendInfoLog("Approaching rate limit. Waiting for $waitTimeSeconds seconds.") | ||
Thread.sleep(waitTimeSeconds * 1000) | ||
} | ||
return block() | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/kotlin/net/leanix/githubagent/interceptor/RateLimitResponseInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package net.leanix.githubagent.interceptor | ||
|
||
import feign.InvocationContext | ||
import feign.ResponseInterceptor | ||
import net.leanix.githubagent.shared.RateLimitMonitor | ||
|
||
class RateLimitResponseInterceptor : ResponseInterceptor { | ||
|
||
override fun intercept( | ||
invocationContext: InvocationContext, | ||
chain: ResponseInterceptor.Chain | ||
): Any { | ||
val result = chain.next(invocationContext) | ||
|
||
val response = invocationContext.response() | ||
if (response != null) { | ||
val headers = response.headers().mapKeys { it.key.lowercase() } | ||
val rateLimitRemaining = headers["x-ratelimit-remaining"]?.firstOrNull()?.toIntOrNull() | ||
val rateLimitReset = headers["x-ratelimit-reset"]?.firstOrNull()?.toLongOrNull() | ||
|
||
if (rateLimitRemaining != null && rateLimitReset != null) { | ||
RateLimitMonitor.updateRateLimitInfo(rateLimitRemaining, rateLimitReset) | ||
} | ||
} | ||
|
||
return result | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
src/main/kotlin/net/leanix/githubagent/shared/RateLimitMonitor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package net.leanix.githubagent.shared | ||
|
||
import org.slf4j.LoggerFactory | ||
|
||
object RateLimitMonitor { | ||
|
||
private val logger = LoggerFactory.getLogger(RateLimitMonitor::class.java) | ||
|
||
@Volatile | ||
private var rateLimitRemaining: Int = Int.MAX_VALUE | ||
|
||
@Volatile | ||
private var rateLimitResetTime: Long = 0 | ||
|
||
private val lock = Any() | ||
|
||
fun updateRateLimitInfo(remaining: Int, resetTimeEpochSeconds: Long) { | ||
synchronized(lock) { | ||
rateLimitRemaining = remaining | ||
rateLimitResetTime = resetTimeEpochSeconds | ||
} | ||
} | ||
|
||
fun shouldThrottle(): Long { | ||
synchronized(lock) { | ||
if (rateLimitRemaining <= THRESHOLD) { | ||
val currentTimeSeconds = System.currentTimeMillis() / 1000 | ||
val waitTimeSeconds = rateLimitResetTime - currentTimeSeconds + 5 | ||
|
||
val adjustedWaitTime = if (waitTimeSeconds > 0) waitTimeSeconds else 0 | ||
logger.warn( | ||
"Rate limit remaining ($rateLimitRemaining) is at or below threshold ($THRESHOLD)." + | ||
" Throttling for $adjustedWaitTime seconds." | ||
) | ||
return adjustedWaitTime | ||
} else { | ||
logger.debug( | ||
"Rate limit remaining ($rateLimitRemaining) is above threshold ($THRESHOLD). No need to throttle." | ||
) | ||
} | ||
return 0 | ||
} | ||
} | ||
|
||
private const val THRESHOLD = 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters