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); }
/// <summary> /// Releases any resources associated with the connection /// </summary> public override void Dispose() { RedisSubscriberConnection subscribers = subscriberChannel; if (subscribers != null) { subscribers.Dispose(); } base.Dispose(); }
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(); }
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"); } } }
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); } }
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); } }
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; }
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; }