I'm calling a 3rd party API that uses OAuth for authentication, and I'm wondering how to make this threadsafe:
var token = _tokenService.GetCurrentToken(); // eg token could be "ABCDEF"
var newToken = oauth.RenewAccessToken(token); // eg newToken could be "123456"
_tokenService.UpdateCurrentToken(newToken); // save newToken to the database
What this does is to use the previous token every time RenewAccessToken()
is called. But there is a problem if two users initiate this at the same time (two different threads will run the code at the same time), and we end up with that code executed in this order:
[Thread 1] var token = _tokenService.GetCurrentToken(); // returns "ABCDEF"
[Thread 2] var token = _tokenService.GetCurrentToken(); // returns "ABCDEF"
[Thread 1] var newToken = oauth.RenewAccessToken("ABCDEF"); // returns "123456"
[Thread 2] var newToken = oauth.RenewAccessToken("ABCDEF");
// throws an invalid token exception
What has happened is that in thread 2, it should actually be calling oauth.RenewAccessToken("123456");
(because that is the latest token value. But the latest token hasnt even been saved to the database yet, so thread 2 always has the wrong value for current token.
What can I do to fix this?
Edit: It has been suggested to use a lock like this:
private object tokenLock = new object();
lock(tokenLock)
{
var token = _tokenService.GetCurrentToken();
var newToken = oauth.RenewAccessToken(token);
_tokenService.UpdateCurrentToken(newToken);
}
Edit 2: The lock didn't actually work anyway, this is from my logs:
[43 22:38:26:9963] Renewing now using token JHCBTW1ZI96FF
[36 22:38:26:9963] Renewing now using token JHCBTW1ZI96FF
[36 22:38:29:1790] OAuthException exception
The first number is the thread id and the second is a timestamp. Both threads executed at the exact same time down to the milliseconds. I don't know why the lock failed to stop thread 36 until after thread 43 had finished.
Edit 3: And again, this time after changing the object tokenLock
to be a class variable instead of a local variable, the lock did not work.
[25 10:53:58:3870] Renewing now using token N95984XVORY
[9 10:53:58:3948] Renewing now using token N95984XVORY
[9 10:54:55:7981] OAuthException exception