Gigi Gigi - 3 months ago 28
C# Question

How does ConnectionMultiplexer deal with disconnects?

The Basic Usage documentation for StackExchange.Redis explains that the

ConnectionMultiplexer
is long-lived and is expected to be reused.

But what about when the connection to the server is broken? Does
ConnectionMultiplexer
automatically reconnect, or is it necessary to write code as in this answer (quoting that answer):

if (RedisConnection == null || !RedisConnection.IsConnected)
{
RedisConnection = ConnectionMultiplexer.Connect(...);
}
RedisCacheDb = RedisConnection.GetDatabase();


Is the above code something good to handle recovery from disconnects, or would it actually result in multiple
ConnectionMultiplexer
instances? Along the same lines, how should the
IsConnected
property be interpreted?

[Aside: I believe the above code is a pretty bad form of lazy initialization, particularly in multithreaded environments - see Jon Skeet's article on Singletons].

Answer

Here is the pattern recommended by the Azure Redis Cache team:

private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => {
    return ConnectionMultiplexer.Connect("mycache.redis.cache.windows.net,abortConnect=false,ssl=true,password=...");
});

public static ConnectionMultiplexer Connection {
    get {
        return lazyConnection.Value;
    }
}

A few important points:

  • It uses Lazy<T> to handle thread-safe initialization
  • It sets "abortConnect=false", which means if the initial connect attempt fails, the ConnectionMultiplexer will silently retry in the background rather than throw an exception.
  • It does not check the IsConnected property, since ConnectionMultiplexer will automatically retry in the background if the connection is dropped.