9

I'm designing a web service which uses Redis as a database, and I want to know the best practices for using Redis connecting with StackService client.

The point is that I've been reading about Redis and I found that the best way to interact with the server is by using a single concurrent connection.

The problem is that despite I'm using PooledRedisClientManager each time that a web client makes a request to the web service I get a one more connected client (opened connection) to the redis server and this number of connected client increases without limit consuming more and more memory.

The sample 'fault' code:

PooledRedisClientManager pooledClientManager = new PooledRedisClientManager("localhost");
var redisClient = pooledClientManager.GetClient();
using (redisClient)
{
   redisClient.Set("key1", "value1");
}

What I did to solve the problem, is create a class implementing the singleton pattern with a static RedisClient var; Which if the redisClient is not initialized creates a new one, and if it is, returns the initialized one.

Solution:

public class CustomRedisPooledClient
{
    private static CustomRedisPooledClient _instance = null;
    public RedisClient redisClient = null;

    // Objeto sincronización para hacer el Lock 
    private static object syncLock = new object();

    private CustomRedisPooledClient()
    {
        redisClient = new RedisClient("localhost");
    }

    public static CustomRedisPooledClient GetPooledClient()
    {
        if (_instance == null)
        {
            lock (syncLock)
            {
                if (_instance == null)
                {
                    _instance = new CustomRedisPooledClient();
                }
            }
        }
        return _instance;
    }
}

CustomRedisPooledClient customRedisPooledClient = CustomRedisPooledClient.GetPooledClient();
using (customRedisPooledClient.redisClient)
{
    customRedisPooledClient.redisClient.Set("key1", "value1");
}

Is this a good practice?

Thank you in advance!

Scott
  • 21,211
  • 8
  • 65
  • 72
Roberto Zamora
  • 250
  • 2
  • 11
  • Why did you pull a **redisClient** from the pool but are not using it? but are using **pooledClientManager** instead? – mythz May 15 '12 at 16:28
  • It was a mistake writing the question, now it's corrected – Roberto Zamora May 15 '12 at 17:34
  • 1
    k, tho I would edit your question because your 'fault code' now works and the **Solution** provided is not ideal. Add what the problem was and refer to the accepted answer for the ideal solution. – mythz May 15 '12 at 17:49

1 Answers1

16

I used PooledRedisClientManager and it works fine:

Sample code that I run only once:

static PooledRedisClientManager pooledClientManager = new PooledRedisClientManager("localhost");

and code I run on many threads:

var redisClient = pooledClientManager.GetClient();
using (redisClient)
{
    redisClient.Set("key" + i.ToString(), "value1");
}

and I have only 11 clients connected to the server.

Scott
  • 21,211
  • 8
  • 65
  • 72
eyossi
  • 4,230
  • 22
  • 20
  • If I do the same I get a new thread at every request made by the browser. I've debugged it and a new thread(client) its created when the line redisClient.Set("key" + i.ToString(), "value1"); is executed and I loose the control and seems it will be open forever. I made a test refreshing the web page that calls the service URL and I've reached 100 connected clients – Roberto Zamora May 15 '12 at 11:03
  • Maybe the problem is that I run the code on every request, Is it? – Roberto Zamora May 15 '12 at 11:04
  • Are you sure you don't run "PooledRedisClientManager pooledClientManager = new PooledRedisClientManager("localhost");" every time? – eyossi May 15 '12 at 11:04
  • Yes I run it in every request, is it wrong? What is the correct use? – Roberto Zamora May 15 '12 at 11:59
  • You need to define a static member that holds the pooledClientManager. For every request you need to reference that static member (**Without creating a new instance of it**) and run the "using (var redisClient = ... " code. Just make sure you don't instantiate the PooledRedisClientManager more than once – eyossi May 15 '12 at 12:06
  • @RoyiNamir Clicked it and it was removed. – eyossi May 12 '14 at 08:19