No the connection returns to the pool as soon as you dispose of it. i.e:
using (var redis = redisManager.GetClient())
{
}
The IdleTimeoout is how long period of inactivity before the redisManager considers the connection to be stale and then discarded. It should be a little lower than the redis-server configured TCP keepalive (default 300 seconds), but otherwise there’s no reason that it should be set so low.
# TCP keepalive.
#
# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
# of communication. This is useful for two reasons:
#
# 1) Detect dead peers.
# 2) Take the connection alive from the point of view of network
# equipment in the middle.
#
# On Linux, the specified value (in seconds) is the period used to send ACKs.
# Note that to close the connection the double of the time is needed.
# On other kernels the period depends on the kernel configuration.
#
# A reasonable value for this option is 60 seconds.
tcp-keepalive 0
class Program
{
private static RedisManagerPool redisManager;
static void Main(string[] args)
{
redisManager = new RedisManagerPool("redis://xxx:6379?db=2");
using (var red = redisManager.GetClient())
{
string val = red.Get<string>("samplekey");
}
Console.WriteLine("First query done");
Console.ReadLine();
//press ENTER after 5 mins
using (var red = redisManager.GetClient())
{
string val = red.Get<string>("samplekey");
}
Console.WriteLine("Second query done");
Console.ReadLine();
}
}
When I launch this console app on my local PC it works fine
On Azure VM (Windows, B2S) same console app throws an exception
To catch it I have to wait 5 mins after the first query, press ENTER to make console app send second query
Any ideas? Maybe there are some inbound / outbound configs on windows which I have to edit?
Can you try using a new RedisManagerPool to check whether its an issue with the existing open connection or just not being able to connect to Redis Azure.
redisManager = new RedisManagerPool("redis://xxx:6379?db=2");
//press ENTER after 5 mins
using (var red = redisManager.GetClient())
{
string val = red.Get<string>("samplekey");
}
Console.WriteLine("Second query done");
Console.ReadLine();
But I don’t really understand how to use redisManager reassignment in my case
There is singleton instance of RedisManagerPool in production (in docs you say that it is thread-safe manager, so it may be used as singleton instance)
I’m using ServiceStack.Redis in my game server and redisManager.GetClient() is called everytime the game finishes.
Should I reassign redisManager after some period of time or there are better options to handle this issue?
class Program
{
private static RedisManagerPool redisManager;
static void Main(string[] args)
{
redisManager = new RedisManagerPool("redis://xxx:6379?db=2");
using (var red = redisManager.GetClient())
{
string val = red.Get<string>("samplekey");
}
Console.WriteLine("First query done");
Console.ReadLine();
//press ENTER after 5 mins
using (var red = redisManager.GetClient())
{
string val = red.Get<string>("samplekey");
}
Console.WriteLine("Second query done");
Console.ReadLine();
}
}
causes exception even on my local PC, so it doesn’t look like that the problem is reproducible only on Azure Windows VM
I’ve tried running this multiple times and was unable to repro the issue, then got sick of waiting for 5 mins each run so I rewrote it in a loop which reruns the code after 6 minutes:
using (var redis = redisManager.GetClient())
{
redis.Set("samplekey", "value");
}
try
{
var i = 0;
while (true)
{
using (var redis = redisManager.GetClient())
{
string val = redis.Get<string>("samplekey");
$$"{DateTime.Now.ToShortTimeString()} {++i} query done: {val}".Print();
}
"Waiting for 6 minutes...".Print();
Thread.Sleep(TimeSpan.FromMinutes(6));
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
So far the output is:
3:58 PM 1 query done: value
Waiting for 6 minutes...
4:04 PM 2 query done: value
Waiting for 6 minutes...
4:10 PM 3 query done: value
Waiting for 6 minutes...
4:16 PM 4 query done: value
Waiting for 6 minutes...
4:22 PM 5 query done: value
Waiting for 6 minutes...
4:28 PM 6 query done: value
Waiting for 6 minutes...
Going to leave it running for another hour to see if I can repro the issue.
4:32 PM 1 query done: value
Waiting for 6 minutes...
4:38 PM 2 query done: value
Waiting for 6 minutes...
4:44 PM 3 query done: value
Waiting for 6 minutes...
4:50 PM 4 query done: value
Waiting for 6 minutes...
4:56 PM 5 query done: value
Waiting for 6 minutes...
5:02 PM 6 query done: value
Waiting for 6 minutes...
5:08 PM 7 query done: value
Waiting for 6 minutes...
5:14 PM 8 query done: value
Waiting for 6 minutes...
5:20 PM 9 query done: value
Waiting for 6 minutes...
5:26 PM 10 query done: value
Waiting for 6 minutes...
Going to have to stop it there because I need to stop all Apps and close or IDEs to clear my local NuGet package cache.
8:12 PM 1 query done: value
Waiting for 6 minutes...
8:18 PM 2 query done: value
Waiting for 6 minutes...
8:24 PM 3 query done: value
Waiting for 6 minutes...
8:30 PM 4 query done: value
Waiting for 6 minutes...
8:36 PM 5 query done: value
Waiting for 6 minutes...
8:42 PM 6 query done: value
Waiting for 6 minutes...
8:48 PM 7 query done: value
Waiting for 6 minutes...
8:54 PM 8 query done: value
Waiting for 6 minutes...
9:00 PM 9 query done: value
Waiting for 6 minutes...
9:06 PM 10 query done: value
Waiting for 6 minutes...
9:12 PM 11 query done: value
Waiting for 6 minutes...
9:18 PM 12 query done: value
Waiting for 6 minutes...
9:24 PM 13 query done: value
Waiting for 6 minutes...
9:30 PM 14 query done: value
Waiting for 6 minutes...
I’ve started running it against one of my redis-servers across the world in Germany to see if I can get a repro…
Ran it for another 1.5 hours against a redis-server instance in Germany with still no issue:
9:31 PM 1 query done: value
Waiting for 6 minutes...
9:37 PM 2 query done:
Waiting for 6 minutes...
9:43 PM 3 query done:
Waiting for 6 minutes...
9:49 PM 4 query done:
Waiting for 6 minutes...
9:55 PM 5 query done:
Waiting for 6 minutes...
10:01 PM 6 query done:
Waiting for 6 minutes...
10:07 PM 7 query done:
Waiting for 6 minutes...
10:13 PM 8 query done:
Waiting for 6 minutes...
10:19 PM 9 query done:
Waiting for 6 minutes...
10:25 PM 10 query done:
Waiting for 6 minutes...
10:31 PM 11 query done:
Waiting for 6 minutes...
10:37 PM 12 query done:
Waiting for 6 minutes...
10:43 PM 13 query done:
Waiting for 6 minutes...
10:49 PM 14 query done:
Waiting for 6 minutes...
10:55 PM 15 query done:
Waiting for 6 minutes...
11:01 PM 16 query done:
Waiting for 6 minutes...
Given it was unable to establish a TCP connection in your last stack trace it’s possible your network or configuration could be faulty. It indicates the Redis Client tried to reconnect up to the default RedisConfig.DefaultRetryTimeout before giving up and throwing.
You can try extending RedisConfig.DefaultRetryTimeout for a longer time or disable connection pooling by using BasicRedisClientManager instead of RedisManagerPool.