Handle Background Refresh token call in Retrofit parallel network calls

Viewed 4066

I am new to android programming and Retrofit , I am making a sample app where i have to make two parallel network calls using access token. The problem comes when access token is expired and return 401 status code , if I see 401 HTTP status code I have to make a call to refresh token with this access token , but problem with parallel calls is that it leads to race condition for refreshing the refresh token , is there any best practice of way to avoid such situation and how to intelligently refresh the token without any conflict.

3 Answers

To avoid race conditions, you could synchronize refresh token code using ReentrantLock. For instance, if request A and request B try to refresh token at the same time, since code is synchronized, refresh A gets to actually refresh the token. Once it completes, request B will run refreshToken() and there's should be some logic that tells request B that token has already been refreshed. An example could be storing timestamp of when the token refresh happens then check if token has been refreshed last 10 seconds.

val lock = ReentrantLock(true)

fun refreshToken(): Boolean {
     lock.lock()
     if (token has been refreshed in last 10 seconds): return true
     api.refresh()
     lock.unlock()

}

If you don't want to use last 10 seconds logic, here's a different approach. Whenever you refresh token, backend returns {accessToken, expiration-timestamp}. Now, request A saves this token and expiration in disk. Request B will just need to check to make sure token is not expired using the timestamp. If request B gets 401 and token has not expired, it means request A has refreshed the token. Sample code:

val lock = ReentrantLock(true)

fun refreshToken(): Boolean {
     lock.lock()
     if (token has not expired): return true
     api.refresh()
     lock.unlock()

}

Otherwise, you probably have to create a queue for refresh token operations as mentioned above.

Related