We use the Redis cache for our web-api app. We use the Microsoft.Extensions.Caching.StackExchangeRedis. After some works were made on Redis server, our app has failed to write to the cache:
"READONLY You can't write against a read only replica"
If I understand correctly, it is because connection is cached by the redis client (in the Microsoft.Extensions.Caching.StackExchangeRedis code).
SetAsync method calls the OnRedisError method in case of error:
...
catch (Exception ex)
{
OnRedisError(ex, cache);
throw;
}
...
In the OnRedisError method the cached connection can be nulled.
private void OnRedisError(Exception exception, IDatabase cache)
{
if (_options.UseForceReconnect && (exception is RedisConnectionException or SocketException))
{
...
// wipe the shared field, but *only* if it is still the cache we were
// thinking about (once it is null, the next caller will reconnect)
var tmp = Interlocked.CompareExchange(ref _cache, null, cache);
...
}
}
And finilly, the UseForceReconnect is
private bool? _useForceReconnect;
internal bool UseForceReconnect
{
get
{
return _useForceReconnect ??= GetDefaultValue();
static bool GetDefaultValue() =>
AppContext.TryGetSwitch("Microsoft.AspNetCore.Caching.StackExchangeRedis.UseForceReconnect", out var value) && value;
}
set => _useForceReconnect = value;
}
But it seems reconnection in case of error in the SetAsync method doesn't work by default. Also it is written here: https://learn.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific#retry-usage-guidance-1
The StackExchange Redis client manages its own retries, but only when establishing a connection to the cache when the application first starts. You can configure the connection timeout, the number of retry attempts, and the time between retries to establish this connection, but the retry policy doesn't apply to operations against the cache.
So it seems there is the feature, which is disabled. Can I just enable it or it is a bad idea?
Is there another way to recreate connection in case of error?
PS: the full code of the client: https://github.com/dotnet/aspnetcore/blob/main/src/Caching/StackExchangeRedis/src/RedisCache.cs#L275