To clarify the response of vangose, I would add that you need to use some kind of locking mechanism. Consider the PHP-ish pseudo-code here:
if (isFallback($token)) { // Log the user in } else { // Usual processing // If token has to be updated, save old token as fallback for a few seconds }
If there are parallel requests, they may appear in the else branch, one request will lead to an update, and the other will lead to the invalidation of the token. The way I solved this is to use a named lock named after $token to wrap the else branch. In addition, all concurrent requests, except for one, will not be able to get a lock, in which case we will sleep a bit and try again (when we try again, we find that the token has become a rollback token).
if (isFallback($token)) { // Log the user in } else { $couldLock = lock($token); if (!$couldLock) { usleep(10000); // Retry, possibly a recursive call } else { // Usual processing // If token has to be updated, save old token as fallback for a few seconds unlock($token); } }
I hope these considerations can be helpful.
source share