Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to synchronize / limit certain async http calls in android

I am making use of the Android Async Http Library in my app to make async http requests.

I have come into a situation in my android app where the following happens. My web api makes use of an access token and a refresh token. On every request that I make I check if the access token is still valid. If it is not I then issue a http post to go get a new access token using the refresh token.

Now i have noticed the following situation.

user of my app leaves their phone inactive for enough time for the access token to expire. When they wake the phone up. In my onResume() function I fire off two separate http requests.

  1. Request 1 checks the access token and determines its not valid. it then issues a refreshAccessToken request.
  2. While Request 1 is waiting for the response, Request 2 also checks the access token and determines its not valid. And it also issues a refreshAccessToken request.
  3. Request 1 returns successfully and updates the access token and refresh token values.
  4. Request 2, then gets a 401 response from the api as the refresh token which it provided has already been used. My application then thinks that there is an error with the refreshToken and logs the user out.

This is obviously incorrect and I would like to avoid it. I have in the mean time, done a double check in the refreshAccessToken onFailed() method. To see if the accessToken is maybe valid again. However this is inefficient as I am still sedning two requests over the air, and my API has to handle the failed refresh attempt.

Question: Now my issue is that i cant use any locks or synchronization as you cannot block the main UI thread in android. And Android Async Http Library handles all of the different threads etc.

like image 512
Zapnologica Avatar asked Sep 05 '25 03:09

Zapnologica


1 Answers

Request 2 also checks the access token and determines its not valid.

This is wrong. Since Request 1 may have already issued refreshAccessToken request, then the state of the access token cannot be determined by consulting the server.

So you need a combined operation getAccessToken() which checks access token, issues refreshAccessToken when needed, and, when called in parallel, only waits for previously called getAccessToken() operation.

UPDATE. refreshAccessToken is a part of a class which serves as a gatekeeper and allows requests to run only if access token is refreshed. If token is not refreshed, gatekeeper sends single request to refresh the token. Meantime, input requests are saved in a queue. When the token is refreshed, the gatekeeper lets saved requests to run.

like image 112
Alexei Kaigorodov Avatar answered Sep 07 '25 23:09

Alexei Kaigorodov