Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement ServiceStack Redis Client with timeout

We are implementing a pattern where our client checks to see if a document exists in Redis, and if it does not, we then fetch the data from the database.

We are trying to handle a case where the Redis server is down or unreachable so we can then immediately fetch from the database.

However, when we test our code by intentionally taking down the Redis server, the call to Redis via the ServiceStack client does not timeout for approximately 20 seconds.

We tried using the RedisClient .SendTimeout property to various values (1000, 100, 1), but the timeout always happens after approx 20 seconds. We also tried using the .Ping() method but have the same problem.

Question: how can we handle the scenario where the Redis server is down and we want to switch to a DB fetch more quickly?

like image 696
Pete Lunenfeld Avatar asked Mar 20 '12 21:03

Pete Lunenfeld


People also ask

How do I set timeout in Redis?

To create a Redis with an expiration time, use the SET command and the EX option to set the expiration time. The EX option takes a number in seconds and sets the number of seconds the key is valid until expiration. You can also use PX to specify the expiration time in Milliseconds.

What is default Redis connection timeout?

The default is 1000 milliseconds. You can modify this by adding a "syncTimeout=2000" (which would give a timeout of 2 seconds) to your configuration string or by using the ConfigurationOptions when you connect to the cache.

What is ServiceStack Redis?

ServiceStack's C# Redis Client is a simple, high-performance and feature-rich C# Client for Redis with native support and high-level abstractions for serializing POCOs and Complex Types supporting both native Sync and Async APIs.


1 Answers

I had a similar problem sending e-mail: sometimes there's no answer and the build-in timeout (of SmtpClient) does nothing. Eventually I'd get a timeout which I believe comes from the underlying TCP/IP layer. I'd set the timeout in the client a little shorter than the "brutal timeout" on Task.Wait.

My solution was to wrap the call in a Task, and use a timeout on that:

        // this special construct is to set a timeout (the SmtpClient timeout does not seem to work)
        var task = Task.Factory.StartNew(() => SendEmail(request));

        if (!task.Wait(6000))
            Log.Error("Could not send mail to {0}. Timeout (probably on TCP layer).".Fmt(request.To));

Maybe something similar would work for you, just replace the SendEmail with a method that does the Redis thing.

like image 113
specimen Avatar answered Sep 21 '22 03:09

specimen