Running a background CoroutineJob in Kotlin to process a batch of Genesys Cloud web messaging transcripts via GET /api/v2/analytics/conversations/summaries. The job pulls a fresh OAuth token at startup, but the batch takes about 45 seconds to complete. About halfway through, the access token expires. The SDK’s automatic refresh logic seems to kick in, but the coroutine flow doesn’t pause for the refresh. It just throws a 401 Unauthorized for the requests queued up during the refresh window.
I’m wrapping the HTTP calls in a custom suspend function that catches HttpClientException. When I see the 401, I manually trigger a refresh using the refresh token endpoint POST /oauth/token. The problem is the timing. The subsequent requests in the batch fail with 401s before the new token is ready. I’ve tried using a Mutex to serialize token access, but the coroutine scheduler seems to execute the next API call before the mutex lock is fully acquired.
Here’s the rough structure:
val mutex = Mutex()
suspend fun fetchData(endpoint: String): Response {
return try {
httpClient.get(endpoint)
} catch (e: HttpClientException) {
if (e.response.status == HTTP_401) {
mutex.lock()
try {
refreshToken()
} finally {
mutex.unlock()
}
// Retry logic here, but it fails immediately
httpClient.get(endpoint)
} else {
throw e
}
}
}
The retry fails because the httpClient instance still holds the old, expired token. I have to invalidate the client cache or create a new client, which feels messy. Is there a standard pattern in the Genesys Cloud Kotlin SDK for handling mid-request token expiration without manual mutex juggling? The docs mention auto-refresh, but it’s clearly not working for long-running batch jobs. Need a clean way to pause the batch, refresh, and resume without losing state.