I have 2 servers for load balancers and each one has 8 worker processors. I want to have a value that is shared among workers in each server. my code is like below:
static string _token;
public async Task<string> GetokenAsync()
{
if (token.isExpire() || string.IsNullOrWhiteSpace(token))
{
await _semaphoreSlim.WaitAsync();
if (token.isExpire() || string.IsNullOrWhiteSpace(token))
{
try
{
token = await GetTokenFromAPIServiceAsync();
}
finally
{
_semaphoreSlim.Release();
}
}
else
_semaphoreSlim.Release();
}
return token;
}
but I guess static variable does not work properly when there are many workers, because i think they manipulate static fileds.
so I decided to use redis instead of static field like below:
public async Task<string> GetokenAsync()
{
var token = await GetFromRedisAsync();
if (string.IsNullOrWhiteSpace(token))
{
await _semaphoreSlim.WaitAsync();
if (token.isExpire() || string.IsNullOrWhiteSpace(token))
{
try
{
token = await GetFromServiceAndSetToRedisAsync();
}
finally
{
_semaphoreSlim.Release();
}
}
else
_semaphoreSlim.Release();
}
return token;
}
is it a good solution to use redis and semaphorSlim for locking threads? is semaphore working among workers or some workers might change value in redis?
If the goal is to share information between different processes on the same server then
SemaphoreSlimis not a solution - it works only for single app instance. For cross-process synchronization (on the same server) you need to look into using namedSemaphoreorMutex.Alternatively you can look into mechanisms provided by Redis to perform synchronization (see this or this for example, also it will enable option to share token between different servers if needed).