swestner
swestner

Reputation: 1917

IRedisSubscription connection

I am using Service Stack to connect to Redis and use the SubPub functionality.

Should I be keeping the IRedisSubscription and IRedisClient instantiation alive? For example should I be assigning it to a class level variable?

Or can I simply scope it within a using statement and Service Stack will handle the persistence?

That is, which of the following examples is correct :

public class RedisPubSub1 : IDisposable {

    private static PooledRedisClientManager ClientPool = new PooledRedisClientManager("connectionString");
    private IRedisSubscription _subscription;
    private IRedisClient _client;

    private Action<string, string> _publish;
    public event Action<string, string> Publish {
        add { _publish += value; }
        remove { _publish -= value; }
    }

    public RedisPubSub1()
    {         
        Task.Factory.StartNew(() =>
            {
                _client = ClientPool.GetClient();
                _subscription = _client.CreateSubscription();
                    {
                        _subscription.OnMessage = EnqueEvent;
                        _subscription.SubscribeToChannels(new string[] { Channel });
                    }
        });
    }

    private void EnqueEvent(string channel, string message)
    {
        if (_publish!= null)
            _publish(channel, message);
    }      

    public void Dispose()
    {
        _subscription.Dispose();
        _client.Dispose();


    }
} }

Or

public class RedisPubSub2 {

    private static PooledRedisClientManager ClientPool = new PooledRedisClientManager("connectionString");

    private Action<string, string> _publish;

    public event Action<string, string> Publish {
        add { _publish += value; }
        remove { _publish -= value; }
    }

    public RedisPubSub2()
    {         
        Task.Factory.StartNew(() =>
            {
                using(var _client = ClientPool.GetClient())
                {
                    using(_subscription = _client.CreateSubscription()
                    {
                        _subscription.OnMessage = EnqueEvent;
                        _subscription.SubscribeToChannels(new string[] { Channel });
                    }
                }
        });
    }

    private void EnqueEvent(string channel, string message)
    {
        if (_publish!= null)
            _publish(channel, message);
    }       }

Upvotes: 2

Views: 876

Answers (1)

mythz
mythz

Reputation: 143319

The SubscribeToChannels is blocking so it doesn't really matter if you keep a reference to the connection or not as it wont dispose unless you end the subscription (i.e. unsubscribe).

It's advisable that you implement some way to unsubscribe from the subscription when you want to, which you'd want to do with the thread holding the active subscription as seen in RedisMqServer example, e.g:

using (var subscription = redisClient.CreateSubscription())
{
    subscription.OnUnSubscribe = channel => 
       Log.Debug("OnUnSubscribe: " + channel);

    subscription.OnMessage = (channel, msg) =>
    {
        if (msg == "STOP")
        {
            Log.Debug("UnSubscribe From All Channels...");
            subscription.UnSubscribeFromAllChannels(); //Un block thread.
            return;
        }

        handleMessage(msg);
    }   

    ...

    //Unsubscribing will unblock this subscription:
    subscription.SubscribeToChannels(QueueNames.TopicIn); //blocks thread
}

Upvotes: 2

Related Questions