public bool ConnectionReady()
 {
     if (_redisConnection == null || _redisConnection.State != RedisConnectionBase.ConnectionState.Open)
     {
         lock (_connectionLock)
         {
             if (_redisConnection == null || _redisConnection.State != RedisConnectionBase.ConnectionState.Open)
             {
                 _redisConnection = new RedisConnection(Host, Port, password: Password);
                 try
                 {
                     _redisConnection.Open();
                     _subscriberConnection = _redisConnection.GetOpenSubscriberChannel();
                     _subscriberConnection.MessageReceived += OnRedisMessageReceived;
                     _subscriberConnection.Error += OnRedisError;
                     return true;
                 } 
                 catch (Exception ex)
                 {
                     return false;
                 }
             }
         }
     }
     return true;
 }
        private void Subscribe()
        {
            channel = gateway.GetConnection().GetOpenSubscriberChannel();
            channel.Closed += OnChannelClosed;

            channel.PatternSubscribe(ChannelPattern, OnMessageRecieved);
        }
 public RedisSignalBus(RedisConnection redisConnection)
 {
     _handlers = new ConcurrentDictionary<string, SafeSet<EventHandler<SignaledEventArgs>>>();
     _redisConnection = redisConnection;
     _subscriberConnection = _redisConnection.GetOpenSubscriberChannel();
     _subscriberConnection.MessageReceived += OnRedisMessageReceived;
 }
        /// <summary>
        /// Subscribe to perform some operation when a change to the preferred/active node is broadcast.
        /// </summary>
        public static void SubscribeToMasterSwitch(RedisSubscriberConnection connection, Action<string> handler)
        {
            if (connection == null) throw new ArgumentNullException("connection");
            if (handler == null) throw new ArgumentNullException("handler");

            connection.Subscribe(RedisMasterChangedChannel, (channel, message) => handler(Encoding.UTF8.GetString(message)));
        }
        public RedisMessageBus(string server, int port, string password, int db, IEnumerable<string> keys, IDependencyResolver resolver)
            : base(resolver)
        {
            _db = db;
            _keys = keys.ToArray();

            _connection = new RedisConnection(host: server, port: port, password: password);

            _connection.Closed += OnConnectionClosed;
            _connection.Error += OnConnectionError;

            // Start the connection
            _connectTask = _connection.Open().Then(() => {
                // Create a subscription channel in redis
                _channel = _connection.GetOpenSubscriberChannel();

                // Subscribe to the registered connections
                _channel.Subscribe(_keys, OnMessage);

                // Dirty hack but it seems like subscribe returns before the actual
                // subscription is properly setup in some cases
                while (_channel.SubscriptionCount == 0) {
                    Thread.Sleep(500);
                }
            });
        }
        /// <summary>
        /// Creates a pub/sub connection to the same redis server
        /// </summary>
        public RedisSubscriberConnection GetOpenSubscriberChannel()
        {
            // use (atomic) reference test for a lazy quick answer
            if (subscriberChannel != null)
            {
                return(subscriberChannel);
            }
            RedisSubscriberConnection newValue = null;

            try
            {
                newValue = SubscriberFactory();
                if (Interlocked.CompareExchange(ref subscriberChannel, newValue, null) == null)
                {
                    // the field was null; we won the race; happy happy
                    var tmp = newValue;
                    newValue = null;
                    return(tmp);
                }
                else
                {
                    // we lost the race; use Interlocked to be sure we report the right thing
                    return(Interlocked.CompareExchange(ref subscriberChannel, null, null));
                }
            }
            finally
            {
                // if newValue still has a value, we failed to swap it; perhaps we
                // lost the thread race, or perhaps an exception was thrown; either way,
                // that sucka is toast
                using (newValue as IDisposable)
                {
                }
            }
        }
        private void Subscribe()
        {
            channel = gateway.GetConnection().GetOpenSubscriberChannel();
            channel.Closed += OnChannelClosed;

            channel.Subscribe(EventKey, OnMessageRecieved);
        }
        private RedisSubscriberConnection SubscriberFactory()
        {
            var conn = new RedisSubscriberConnection(Host, Port, IOTimeout, Password, 100);

            conn.Name = Name;
            conn.SetServerVersion(this.ServerVersion, this.ServerType);
            conn.Error += OnError;
            conn.Open();
            return(conn);
        }
Exemple #9
0
        /// <summary>
        ///     Releases any resources associated with the connection
        /// </summary>
        public override void Dispose()
        {
            RedisSubscriberConnection subscribers = subscriberChannel;

            if (subscribers != null)
            {
                subscribers.Dispose();
            }
            base.Dispose();
        }
Exemple #10
0
 internal static RedisSubscriberConnection GetSubscriberConnection()
 {
     var conn = new RedisSubscriberConnection(host, unsecuredPort);
     conn.Error += (s, args) =>
     {
         Trace.WriteLine(args.Exception.Message, args.Cause);
     };
     conn.Open();
     return conn;
 }
        public void OnChannelClosed(object sender, EventArgs e)
        {
            if (channel != null) {
                channel.Closed -= OnChannelClosed;
                channel.Dispose();
                channel = null;
            }

            Subscribe();
        }
        /// <summary>
        /// Subscribe to perform some operation when a change to the preferred/active node is broadcast.
        /// </summary>
        public static void SubscribeToMasterSwitch(RedisSubscriberConnection connection, Action <string> handler)
        {
            if (connection == null)
            {
                throw new ArgumentNullException("connection");
            }
            if (handler == null)
            {
                throw new ArgumentNullException("handler");
            }

            connection.Subscribe(RedisMasterChangedChannel, (channel, message) => handler(Encoding.UTF8.GetString(message)));
        }
        /// <summary>
        /// This is a small application to test event subscriptions in redis - which are required for automatic expiry of cache items
        /// if subscriptions dont work try setting the redis config :
        /// config set notify-keyspace-events Ex
        /// </summary>
        /// <param name="args"></param>
        private static void Main(string[] args)
        {
            Console.WriteLine("Start");

            _conn = new RedisConnection("localhost");
            var c = _conn.Open();
            c.Wait();
            Console.WriteLine("Conn : " + _conn.State);

            _conn.Keys.Remove(_db, "_expireys");


            _subConn = new RedisSubscriberConnection("localhost");
            var s = _subConn.Open();
            s.Wait();
            Console.WriteLine("SubConn : " + _subConn.State);

            channel = _conn.GetOpenSubscriberChannel();
            Thread.Sleep(100);

            Console.WriteLine("Channel : " + channel.State);

            channel.PatternSubscribe("*:expired", OnExecutionCompleted).Wait();

            Console.WriteLine("Subscriptions : " + channel.SubscriptionCount);


            Set(1, 4);
            Thread.Sleep((6 * 1000) );
            if (received > 0)
            {
                Console.WriteLine("Subscriptions have worked");
            }
            else
            {
                Console.WriteLine("Subscriptions have not worked");
            }

            Console.ReadKey();
        }
Exemple #14
0
        private void TestSubscriberNameOnRemote(bool setName)
        {
            string id = Config.CreateUniqueName();

            using (var pub = new RedisConnection(Config.RemoteHost, allowAdmin: true))
            using (var sub = new RedisSubscriberConnection(Config.RemoteHost))
            {
                List<string> errors = new List<string>();
                EventHandler<BookSleeve.ErrorEventArgs> errorHandler = (sender, args) =>
                {
                    lock (errors) errors.Add(args.Exception.Message);
                };
                pub.Error += errorHandler;
                sub.Error += errorHandler;

                if (setName)
                {
                    pub.Name = "pub_" + id;
                    sub.Name = "sub_" + id;
                }
                int count = 0;
                var subscribe = sub.Subscribe("foo"+id, (key,payload) => Interlocked.Increment(ref count));

                Task pOpen = pub.Open(), sOpen = sub.Open();
                pub.WaitAll(pOpen, sOpen, subscribe);

                Assert.AreEqual(0, Interlocked.CompareExchange(ref count, 0, 0), "init message count");
                pub.Wait(pub.Publish("foo" + id, "hello"));

                PubSub.AllowReasonableTimeToPublishAndProcess();
                var clients = setName ? pub.Wait(pub.Server.ListClients()) : null;
                Assert.AreEqual(1, Interlocked.CompareExchange(ref count, 0, 0), "got message");
                lock (errors)
                {
                    foreach (var error in errors)
                    {
                        Console.WriteLine(error);
                    }
                    Assert.AreEqual(0, errors.Count, "zero errors");
                }
                if (setName)
                {
                    Assert.AreEqual(1, clients.Count(x => x.Name == pub.Name), "pub has name");
                    Assert.AreEqual(1, clients.Count(x => x.Name == sub.Name), "sub has name");
                }
            }
        }
Exemple #15
0
        public void TestForcedSubscriberName()
        {
            using (var conn = Config.GetUnsecuredConnection(allowAdmin: true, open: true, waitForOpen: true))
            using (var sub = new RedisSubscriberConnection(conn.Host, conn.Port))
            {
                var task = sub.Subscribe("foo", delegate { });
                string name = Config.CreateUniqueName();
                sub.Name = name;
                sub.SetServerVersion(new Version("2.6.9"), ServerType.Master);
                sub.Wait(sub.Open());
                sub.Wait(task);
                Assert.AreEqual(1, sub.SubscriptionCount);

                if (!conn.Features.ClientName) Assert.Inconclusive();
                var clients = conn.Wait(conn.Server.ListClients()).Where(c => c.Name == name).ToList();
                Assert.AreEqual(1, clients.Count, "number of clients");
            }
        }
        private Task ConnectToRedis()
        {
            if (_connection != null)
            {
                _connection.Closed -= OnConnectionClosed;
                _connection.Error -= OnConnectionError;
                _connection.Dispose();
                _connection = null;
            }

            // Create a new connection to redis with the factory
            RedisConnection connection = _connectionFactory();

            connection.Closed += OnConnectionClosed;
            connection.Error += OnConnectionError;

            try
            {
                Trace.TraceInformation("Connecting...");

                // Start the connection
                return connection.Open().Then(() =>
                {
                    Trace.TraceInformation("Connection opened");

                    // Create a subscription channel in redis
                    RedisSubscriberConnection channel = connection.GetOpenSubscriberChannel();

                    // Subscribe to the registered connections
                    channel.Subscribe(_key, OnMessage);

                    // Dirty hack but it seems like subscribe returns before the actual
                    // subscription is properly setup in some cases
                    while (channel.SubscriptionCount == 0)
                    {
                        Thread.Sleep(500);
                    }

                    Trace.TraceVerbose("Subscribed to event " + _key);

                    _channel = channel;
                    _connection = connection;
                });
            }
            catch (Exception ex)
            {
                Trace.TraceError("Error connecting to redis - " + ex.GetBaseException());

                return TaskAsyncHelper.FromError(ex);
            }
        }
Exemple #17
0
        private Task ConnectToRedis()
        {
            if (_connection != null)
            {
                _connection.Closed -= OnConnectionClosed;
                _connection.Error -= OnConnectionError;
                _connection.Dispose();
                _connection = null;
            }

            // Create a new connection to redis with the factory
            RedisConnection connection = _connectionFactory();

            connection.Closed += OnConnectionClosed;
            connection.Error += OnConnectionError;

            try
            {
                _trace.TraceInformation("Connecting...");

                // Start the connection
                return connection.Open().Then(() =>
                {
                    _trace.TraceInformation("Connection opened");

                    // Create a subscription channel in redis
                    RedisSubscriberConnection channel = connection.GetOpenSubscriberChannel();
                    channel.CompletionMode = ResultCompletionMode.PreserveOrder;

                    // Subscribe to the registered connections
                    return channel.Subscribe(_key, OnMessage).Then(() =>
                    {
                        _trace.TraceVerbose("Subscribed to event " + _key);

                        _channel = channel;
                        _connection = connection;
                    });
                });
            }
            catch (Exception ex)
            {
                _trace.TraceError("Error connecting to Redis - " + ex.GetBaseException());

                return TaskAsyncHelper.FromError(ex);
            }
        }
Exemple #18
0
        protected override void EnqueueJsonEvent(string data, string target, string eventName)
        {
            var connection = GetOpenConnection();

            string[] subscribers;
            string eventKey = target + ":" + eventName;

            if (_SubscribedToSubscribersChangesChannel != null &&
                _SubscribedToSubscribersChangesChannel.State != RedisConnectionBase.ConnectionState.Open &&
                _SubscribedToSubscribersChangesChannel.State != RedisConnectionBase.ConnectionState.Opening)
            {
                // connection dropped, create a new one
                _SubscribedToSubscribersChangesChannel = null;
                ClearSubscribersCache();
            }
            if (_SubscribedToSubscribersChangesChannel == null)
            {
                _SubscribedToSubscribersChangesChannel = connection.GetOpenSubscriberChannel();
                _SubscribedToSubscribersChangesChannel.Subscribe(GetRedisKey("events:subscriberschanges"), (message, bytes) =>
                {
                    if (Roque.Core.RoqueTrace.Switch.TraceInfo)
                    {
                        Trace.TraceInformation("[REDIS] Subscribers added to {0}, clearing subscribers cache", Name);
                    }
                    ClearSubscribersCache();
                });
                if (Roque.Core.RoqueTrace.Switch.TraceVerbose)
                {
                    Trace.TraceInformation("[REDIS] Listening for subscribers changes on queue {0}", Name);
                }
            }

            if (DateTime.Now.Subtract(_SubscribersCacheLastClear) > (SubscribersCacheExpiration ?? DefaultSubscribersCacheExpiration))
            {
                ClearSubscribersCache();
            }

            if (!_SubscribersCache.TryGetValue(eventKey, out subscribers))
            {
                subscribers = connection.SortedSets.Range(0, GetRedisKey("events:{0}:subscribers", eventKey), 0, -1).Result
                    .Select(set => Encoding.UTF8.GetString(set.Key)).ToArray();
                _SubscribersCache[eventKey] = subscribers;
            }
            if (subscribers == null || subscribers.Length == 0)
            {
                if (RoqueTrace.Switch.TraceVerbose)
                {
                    Trace.TraceInformation(string.Format("No subscriber for this event, enqueue cancelled. Event: {0}:{1}, Queue:{2}", target, eventName, Name));
                }
                Thread.Sleep(10000);
            }
            else
            {
                foreach (var subscriber in subscribers)
                {
                    connection.Lists.AddFirst(0, GetRedisKeyForQueue(subscriber), data);
                }
                if (RoqueTrace.Switch.TraceVerbose)
                {
                    Trace.TraceInformation(string.Format("Event published to queues: {0}. Event: {1}:{2}", string.Join(", ", subscribers), target, eventName));
                }
            }
        }
 private RedisSubscriberConnection SubscriberFactory()
 {
     var conn = new RedisSubscriberConnection(Host, Port, IOTimeout, Password, 100);
     conn.Error += OnError;
     conn.Open();
     return conn;
 }
Exemple #20
0
        public override string[] GetSubscribersForEvent(string target, string eventName)
        {
            string[] subscribers;
            string eventKey = target + ":" + eventName;
            RedisConnection connection = null;

            if (_SubscribedToSubscribersChangesChannel != null &&
                _SubscribedToSubscribersChangesChannel.State != RedisConnectionBase.ConnectionState.Open &&
                _SubscribedToSubscribersChangesChannel.State != RedisConnectionBase.ConnectionState.Opening)
            {
                // connection dropped, create a new one
                _SubscribedToSubscribersChangesChannel = null;
                ClearSubscribersCache();
            }
            if (_SubscribedToSubscribersChangesChannel == null)
            {
                if (connection == null)
                {
                    connection = Connection.GetOpen();
                }
                _SubscribedToSubscribersChangesChannel = connection.GetOpenSubscriberChannel();
                _SubscribedToSubscribersChangesChannel.Subscribe(GetRedisKey("events:subscriberschanges"), (message, bytes) =>
                {
                    RoqueTrace.Source.Trace(TraceEventType.Information, "[REDIS] Subscribers added to {0}, clearing subscribers cache", Name);
                    ClearSubscribersCache();
                });
                RoqueTrace.Source.Trace(TraceEventType.Verbose, "[REDIS] Listening for subscribers changes on queue {0}", Name);
            }

            if (DateTime.Now.Subtract(_SubscribersCacheLastClear) > (SubscribersCacheExpiration ?? DefaultSubscribersCacheExpiration))
            {
                ClearSubscribersCache();
            }

            if (!_SubscribersCache.TryGetValue(eventKey, out subscribers))
            {
                if (connection == null)
                {
                    connection = Connection.GetOpen();
                }
                subscribers = connection.SortedSets.Range(0, GetRedisKey("events:{0}:subscribers", eventKey), 0, -1).Result
                    .Select(set => Encoding.UTF8.GetString(set.Key)).ToArray();
                _SubscribersCache[eventKey] = subscribers;
            }
            return subscribers;
        }