Avoiding multiple concurrent requests to rotate Refresh Token

How to deal with concurrent API requests when rotating Refresh Token in an OAuth2 authentication flow

Shahab Rauf
Bazaar Engineering
3 min readNov 21, 2021

--

The dark side of overusing concurrency

Concurrency can be a big source of performance boost for any application and it’s arguably one of the rarest types of optimization applied to any working system. Concurrency is a technique in which any number of tasks are executed in a manner that gives the illusion of them being executed in parallel. Although it’s considered a good practice, in real life code that follows a sequential or non-concurrent type of execution is predictable and much simpler to comprehend. In this manner, concurrency can be related to another programming technique that is famous for complicating flows i.e. recursion. The only difference is that in the case of recursion, we don’t get any proclaimed benefits like speed or memory boost.

Problem with concurrent refresh token rotations

In the technical world, we achieve enormous benefits through concurrency, but we have to be conventional and run programs sequentially at some places. One of the big problems many applications face is multiple refresh token requests through different threads or concurrent tasks at the same time. When we hit parallel requests in our system and all of them need to be authenticated from the server then whenever the authentication token expires all parallel API requests fail and attempt to refresh token from the server. The server facilitates all requests and gives a new token for authentication. As the result, multiple tokens would have been generated for a session. We need synchronization to resolve this particular problem. We need to synchronize blocks of code that run sequentially even if the same code block is running through different threads or concurrent tasks.

Solving using Synchronized code blocks

Synchronized blocks or methods have been used to write thread-safe code by avoiding memory inconsistency errors. Nowadays you can achieve thread-safety by using advanced concurrency API instead of synchronized blocks. A synchronized block is synchronized on some object. All synchronized blocks synchronized on the same object can only have one thread executing inside them at a time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.

Let’s discuss how we can resolve these parallel refresh token requests by multiple threads or concurrent tasks. We are selecting Kotlin as our language but you can use any language and apply this solution at any platform using tools provided by that platform.

Further, You can also add this code block in Okhttp Authenticator which will run this code block whenever API returns 401. It will also be useful if you are using the Okhttp client in Android.

Here you can find the complete source code that can help you resolve the problem.

In conclusion, as witnessed in the examples above, I think one fact of concurrency can be clearly stated that its overuse can make your execution flows almost as complicated as grasping its concept the very first time. In some extreme cases, introducing concurrency to an existing system can make it so complicated that it only slows down any new development, ironically making developers slower than their code.

— Thanks Bazaar for encouraging me to write my first story.
Special thanks to Sarang and Alirazarizwe for helping me shape this story well.

--

--

Shahab Rauf
Bazaar Engineering

Engineering @ Bazaar technologies, x Golootlo | x YapJobs