Forwarding timeout after timeout when calling GetClient

I hate questions that have "Not enough information." Therefore, I will try to give detailed information. And in this case, this is the code.

Server: 64 bit https://github.com/MSOpenTech/redis/tree/2.6/bin/release

There are three classes:

DbOperationContext.cs : https://gist.github.com/glikoz/7119628

PerRequestLifeTimeManager.cs : https://gist.github.com/glikoz/7119699

RedisRepository.cs https://gist.github.com/glikoz/7119769

We use Redis with Unity.

In this case, we get this strange message:

"The reuse timeout has expired. The timeout period expires before the connection is received from the pool. Perhaps this was due to the use of all the merged connections.";

We checked these:

  • Problem with configuration problem

  • Are we using the wrong RedisServer.exe

  • Is there any architectural problem

Any idea? Any similar story?

Thanks.

Additional Information 1

There is no answer to the question about connecting to the server (I checked it with the redis-cli.exe command)

+7
servicestack redis
source share
1 answer

I continued to debug this issue and fixed many things on my platform to avoid this exception. Here is what I did to solve the problem:

Summary:

People encountering this exception should check:

  • That the PooledRedisClientsManager (IRedisClientsManager) is registered in the Singleton area
  • What RedisMqServer (IMessageService) is registered in Singleton scope
  • So that the RedisClient utility returned from any of the above is correctly removed to ensure that the merged clients are not out of date.

The solution to my problem:

First of all, this exception is thrown by the PooledRedisClient pool because it has no more empty connections available .

I register all the necessary Redis elements in the StructureMap IoC container (not a unity, as in the case of the author). Thanks to this post, I was reminded that the PooledRedisClientManager should be a single - I also decided to register RedisMqServer as a singleton:

ObjectFactory.Configure(x => { // register the message queue stuff as Singletons in this AppDomain x.For<IRedisClientsManager>() .Singleton() .Use(BuildRedisClientsManager); x.For<IMessageService>() .Singleton() .Use<RedisMqServer>() .Ctor<IRedisClientsManager>().Is(i => i.GetInstance<IRedisClientsManager>()) .Ctor<int>("retryCount").Is(2) .Ctor<TimeSpan?>().Is(TimeSpan.FromSeconds(5)); // Retrieve a new message factory from the singleton IMessageService x.For<IMessageFactory>() .Use(i => i.GetInstance<IMessageService>().MessageFactory); }); 

My "BuildRedisClientManager" function looks like this:

 private static IRedisClientsManager BuildRedisClientsManager() { var appSettings = new AppSettings(); var redisClients = appSettings.Get("redis-servers", "redis.local:6379").Split(','); var redisFactory = new PooledRedisClientManager(redisClients); redisFactory.ConnectTimeout = 5; redisFactory.IdleTimeOutSecs = 30; redisFactory.PoolTimeout = 3; return redisFactory; } 

Then, when it comes to creating messages, it is very important that the disposed RedisClient is properly disposed of, otherwise we will encounter the terrible โ€œTimeout expiredโ€ (thanks to this message ). I have the following helper code to send a message to a queue:

 public static void PublishMessage<T>(T msg) { try { using (var producer = GetMessageProducer()) { producer.Publish<T>(msg); } } catch (Exception ex) { // TODO: Log or whatever... I'm not throwing to avoid showing users that we have a broken MQ } } private static IMessageQueueClient GetMessageProducer() { var producer = ObjectFactory.GetInstance<IMessageService>() as RedisMqServer; var client = producer.CreateMessageQueueClient(); return client; } 

I hope this also helps solve your problem.

+9
source share

All Articles