I am having difficulty with the 1.1.0.5 version of Booksleeve in VS2010 working the way I intend to use it. What's happening is after perform and wait for an operation, Booksleeve sometimes leaves the connection in a closed state, so operations down stream throw exceptions.
The simplest issue I am having is this:
static void Main(string[] args)
{
Func<RedisConnection> getNewRedisConnection = () =>
{
RedisConnection conn = new RedisConnection("Belasco");
conn.Error += (obj, eArgs) => { throw eArgs.Exception; };
return conn;
};
RedisConnection redisConn = null;
TaskScheduler.UnobservedTaskException += new EventHandler<UnobservedTaskExceptionEventArgs>(TaskScheduler_UnobservedTaskException);
redisConn = getNewRedisConnection();
redisConn.Open();
var test1 = redisConn.Sets.GetAllString(0, "test1");
var testValues1 = test1.Result;
//var testValues1 = redisConn.Wait(test1);
var test2 = redisConn.Sets.GetAllString(0, "test2");
var testValues2 = test2.Result;
//var testValues2 = redisConn.Wait(test2);
redisConn.Close(false);
Console.WriteLine("Done");
Console.ReadKey();
}
static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
throw new NotImplementedException();
}
Line var test2 = redisConn.Sets.GetAllString(0, "test2");
throws 'The queue is closed' exception.
Now if I close and re-open the connection inbetween the requests, things seemingly work.
var test1 = redisConn.Sets.GetAllString(0, "test1");
var testValues1 = test1.Result;
//var testValues1 = redisConn.Wait(test1);
redisConn.Close(false);
redisConn = getNewRedisConnection();
redisConn.Open();
var test2 = redisConn.Sets.GetAllString(0, "test2");
var testValues2 = test2.Result;
//var testValues2 = redisConn.Wait(test2);
However if I perform a "setting" operation, all seems to go back to broken.
redisConn = getNewRedisConnection();
redisConn.Open();
var test0 = redisConn.Sets.Add(0, "test1", new string[] { "11", "22", "33", "44", "55" });
redisConn.Wait(test0);
redisConn.Close(false);
redisConn = getNewRedisConnection();
redisConn.Open();
var test1 = redisConn.Sets.GetAllString(0, "test1");
var testValues1 = test1.Result;
//var testValues1 = redisConn.Wait(test1);
redisConn.Close(false);
redisConn = getNewRedisConnection();
redisConn.Open();
var test2 = redisConn.Sets.GetAllString(0, "test2");
var testValues2 = test2.Result;
//var testValues2 = redisConn.Wait(test2);
I also have the same issues with Transactions, but I feel it's stemming from the same issue. The reason why I need to retrieve values, then queue up another command is because my later actions with Redis are determined based on what values I get back!
Firstly, don't close connect ions eagerly here. BookSleeve is designed to be used as a thread-safe multiplexer, taking load from any random number of callers at the same time. There are overheads in opening a connection. Now, there are a few ways a red is connection can become closed:
My guess here is that the server has a connection timeout configured. I don't know about 1.1.*, but automatic timeout configuration detection and keep-alive "ping" messages were added at some point, which help. You can check the timeout via "config get timeout" in redis-cli. If this is the issue, you may find upgrading client version helps. In some builds you can also specify a timeout configuration manually (if you want to overrule the server).
For unexpected data - that is unlikely, but there are a few events you can hook to detect, log and react to this.