I have followed the recommendations here for using ServiceStack.Redis with Web API 2 and AutoFac dependency injection, i.e.
protected void Application_Start()
{
ClientsManager = new PooledRedisClientManager(RedisUri);
...
private void ConfigureDependencyResolver(HttpConfiguration configuration)
{
var builder = new ContainerBuilder();
builder.RegisterType<MyRedisRepository>()
.As<IMyRedisRepository>()
.PropertiesAutowired()
.InstancePerRequest();
builder.Register(c => ClientsManager.GetClient()).InstancePerRequest();
...
However the following exception is periodically being thrown: “System.TimeoutException, Redis Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use.”
The ServiceStack documentation says that “Client Managers are connection factories which is ideally registered as a Singleton either in your IOC or static classes”. In this case, should the ContainerBuilder register the clients manager as a singleton instead?, i.e.:
This exception is due to the Client not being released back into the pool after it’s used.
You should only be registering the ClientsManager as a singleton in the IOC, e.g:
builder.Register<IRedisClientsManager>(c =>
new PooledRedisClientManager(RedisUri)).SingleInstance();
Then resolving the client whenever you need it and dispose of it when you’re done with it, e.g. with a using {} statement.
public IRedisClientsManager RedisManager { get; set; }
public void Method()
{
using (var redis = RedisManager.GetClient())
{
//use redis...
}
}
When the redis client is disposed it gets released back into the pool.
To reduce the boilerplate of accessing Redis and ensuring it’s properly disposed you can adopt a lazy property in a base class, e.g:
public abstract class ServiceBase : IDisposable
{
public virtual IRedisClientsManager RedisManager { get; set; }
private IRedisClient redis;
public virtual IRedisClient Redis
{
get { return redis ?? (redis = RedisManager.GetClient()); }
}
public override void Dispose()
{
base.Dispose();
if (redis != null)
redis.Dispose();
}
}
Where your sub classes can now just access base.Redis whenever it needs access to a new Redis instance where the Dispose() method takes care of releasing the instance back into the pool when the Service is disposed.