public void CreateSubscription(SubscriptionInfo subscriptionInfo, bool isUserOperation = true) { SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); ClientSubscriptionManager clientSubscriptionManger = null; if (AddSubscription(subscriptionInfo, subscriptionIdentifier, isUserOperation)) { lock (_mutex) { if (subscriptionInfo.SubPolicyType != SubscriptionPolicyType.EventSubscription) { _subscriptionLoadBalancer.Add(subscriptionIdentifier); } //while state transfer if any durable subscription has no active subscriber if (subscriptionInfo.ClientId != null) { if (!_subscribers.TryGetValue(subscriptionInfo.ClientId, out clientSubscriptionManger)) { clientSubscriptionManger = new ClientSubscriptionManager(this, subscriptionInfo.ClientId); _subscribers.Add(subscriptionInfo.ClientId, clientSubscriptionManger); } clientSubscriptionManger.AddSubscription(subscriptionInfo); } } if (_listener != null) { _listener.OnSubscriptionCreated(this); } } }
public async void Test_filter_matches_one_of_two() { // Arrange _mockFilterFactory.Setup(f => f.GetExpressionAsync("Topic = 'topic0' and A")) .Returns(() => Task.FromResult(Mock.Of <IFilterExpression>(e => e.EvaluateAsync(It.IsAny <IReadOnlyDictionary <string, object> >()) == Task.FromResult <IComparable>(true)))); _mockFilterFactory.Setup(f => f.GetExpressionAsync("Topic = 'topic0' and B")) .Returns(() => Task.FromResult(Mock.Of <IFilterExpression>(e => e.EvaluateAsync(It.IsAny <IReadOnlyDictionary <string, object> >()) == Task.FromResult <IComparable>(false)))); var subscriptionFoo = new SubscriptionIdentifier("topic0", "A"); var subscriptionOffice = new SubscriptionIdentifier("topic0", "B"); var subscriptions = new[] { new KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate>(subscriptionOffice, (topic, filter, message) => Assert.Fail("You are not supposed to be here.")), new KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate>(subscriptionFoo, (topic, filter, message) => Assert.Fail("You are not supposed to be here.")) }; // Act var callbacks = await _filteringService.Filter(_messageContextMock.Object, subscriptions); //Assert Assert.That(callbacks.Count() == 1, Is.True); Assert.That(callbacks.Any(p => p.Key == subscriptionFoo), Is.True); Assert.That(callbacks.Any(p => p.Key == subscriptionOffice), Is.False); }
private bool AssignMessageToSubscriber(SubscriptionInfo subscriptionInfo, Message message) { HashSet <SubscriptionIdentifier> subscriptionIdentifierList; ClientSubscriptionManager client; SubscriptionIdentifier subscriptionIdentity = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); Subscriptions subscriptions; _subscriptions.TryGetValue(subscriptionIdentity, out subscriptions); if (subscriptions == null) { return(false); } if (/*client.IsActive &&*/ subscriptions.IsActive()) { lock (_mutex) { if (_subscribers.TryGetValue(subscriptionInfo.ClientId, out client)) { if (client.AssignMessageToSubscription(message, subscriptionInfo)) { SubscriptionIdentifier subIdentifier = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); HashSet <SubscriptionIdentifier> subscriptionId; } return(true); } } } return(false); }
public async void Test_logging_when_filter_fail() { var subscriptionFoo = new SubscriptionIdentifier("topic0", "A"); var subscriptionOffice = new SubscriptionIdentifier("topic0", "B"); _mockFilterFactory.Setup(f => f.GetExpressionAsync("Topic = 'topic0' and A")) .Returns(() => Task.FromResult(Mock.Of <IFilterExpression>(e => e.EvaluateAsync(It.IsAny <IReadOnlyDictionary <string, object> >()) == Task.FromResult <IComparable>(true)))); var subscriptions = new[] { new KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate>(subscriptionOffice, (topic, filter, message) => Assert.Fail("You are not supposed to be here.")), new KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate>(subscriptionFoo, (topic, filter, message) => Assert.Fail("You are not supposed to be here.")) }; // Act var callbacks = await _filteringService.Filter(_messageContextMock.Object, subscriptions); // Assert // test that we traced a message _mockTraceListener.Verify((t) => t.TraceEvent( It.IsAny <TraceEventCache>(), It.IsAny <string>(), TraceEventType.Error, It.IsAny <int>(), It.IsAny <string>(), It.IsAny <object[]>())); // trace that even though we had an error, the callbacks which were tested successfully came back Assert.That(callbacks.Any(p => p.Key == subscriptionFoo), Is.True); }
internal void UnSubscribe(TopicSubscription subscription, bool remove = false, bool dispose = false) { try { SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscription.SubscriptionName, subscription.GetSubscriptionPolicyType); _readerWriterLock.AcquireReaderLock(Timeout.Infinite); if (_isDisposed) { return; } _cacheImpl.UnSubscribe(Name, subscription.SubscriptionName, subscription.GetSubscriptionPolicyType, SubscriptionType.Subscriber, dispose); if (remove) { lock (_subscriptions) { _subscriptions.Remove(subscriptionIdentifier); } } _parent.StopPollingIfRequired(this); } finally { _readerWriterLock.ReleaseReaderLock(); } }
private bool RequeMessage(Message message, SubscriptionIdentifier subscriptionIdentifier) { HashSet <SubscriptionIdentifier> assignedSubscriptions; if (!message.MessageMetaData.EverAcknowledged && message.MessageMetaData.IsAssigned && !message.MessageMetaData.HasSubscriptions) { message.MessageMetaData.IsAssigned = false; message.MessageMetaData.AssigmentTime = null; //agains; enque for assignment switch (message.MessageMetaData.SubscriptionType) { case SubscriptionType.Subscriber: _unassignedMessages.Enqueue(message.MessageId, message); break; } return(true); } else if (message.MessageMetaData.Delivered) { _deliveredMessages.Enqueue(message.MessageId, message); if (_listener != null) { _listener.OnMessageDelivered(this); } } return(false); }
public async void Test_dispatch_dispatches() { // Arrange var subscription = new SubscriptionIdentifier("foo", "B=1"); MessageBusCallbackDelegate emptyDelegate = (topic, filter, message) => { }; MessageBusCallbackDelegate testCallbackDelegate = (topic, filter, message) => { Assert.Pass("Callback successfully called"); }; var mockMessage = new Mock <IMagicHubMessage>(); _mockFilteringService .Setup(f => f.Filter( It.IsAny <IReadOnlyDictionary <string, object> >(), It.IsAny <IEnumerable <KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate> > >())) .Returns(Task.FromResult <IEnumerable <KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate> > >(new[] { new KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate>( subscription, testCallbackDelegate) })); _dispatcher.Subscribe(subscription, emptyDelegate); // Act await _dispatcher.DispatchMessage(mockMessage.Object); }
internal void ClientDisconnected(SubscriptionInfo subscriptionInfo) { lock (this) { SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); SubscriptionIdentifier[] messageSubscriptionKey = new SubscriptionIdentifier[_messageSubscriptions.Count]; SubscriptionIdentifier[] deliverySubscriptionKeys = new SubscriptionIdentifier[_deliverySubscriptions.Count]; _deliverySubscriptions.Keys.CopyTo(deliverySubscriptionKeys, 0); _messageSubscriptions.Keys.CopyTo(messageSubscriptionKey, 0); foreach (var item in messageSubscriptionKey) { subscriptionInfo.SubscriptionId = item.SubscriptionName; subscriptionInfo.Type = Common.Enum.SubscriptionType.Subscriber; subscriptionInfo.SubPolicyType = item.SubscriptionPolicy; RemoveSubscription(subscriptionInfo); } foreach (var item in deliverySubscriptionKeys) { subscriptionInfo.SubscriptionId = item.SubscriptionName; subscriptionInfo.SubPolicyType = item.SubscriptionPolicy; subscriptionInfo.Type = Common.Enum.SubscriptionType.Publisher; RemoveSubscription(subscriptionInfo); } if (_subscriptionListener != null) { _subscriptionListener.OnSubscriptionInstanceRemoved(messageSubscriptionKey, this.ClientID); } } }
private bool RemoveSubscription(SubscriptionIdentifier subIdentifier, SubscriptionInfo subInfo, bool isDispose = false) { Subscriptions subscription; lock (_mutex) { if (_subscriptions.TryGetValue(subIdentifier, out subscription)) { if (subIdentifier.SubscriptionPolicy == SubscriptionPolicyType.NonDurableExclusiveSubscription) { _subscriptions.Remove(subIdentifier); } else { subscription.Remove(subInfo.ClientId); if (!subscription.IsActive() && isDispose == false) { _subscriptions.Remove(subIdentifier); //_subscriptionExpirationIndex.Remove(subIdentifier); } } } } return(RemoveSubscriber(subInfo)); }
public bool AssignMessageToSubscription(Message message, SubscriptionInfo subscriptionInfo) { lock (this) { SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); if (_dipsoed) { return(false); } if (message.MessageMetaData.SubscriptionType != subscriptionInfo.Type) { return(false); } Subscribers subscription = null; switch (message.MessageMetaData.SubscriptionType) { case Common.Enum.SubscriptionType.Subscriber: if (subscriptionInfo.SubscriptionId != null) { if (!_messageSubscriptions.TryGetValue(subscriptionIdentifier, out subscription)) { return(false); } } if (_messageSubscriptions.Count > 0 && !_messages.Contains(message.MessageId)) { _messages.Add(message.MessageId, message); } break; case Common.Enum.SubscriptionType.Publisher: if (!_deliverySubscriptions.TryGetValue(subscriptionIdentifier, out subscription)) { return(false); } if (!_delivryNotificationMessages.Contains(message.MessageId)) { _delivryNotificationMessages.Add(message.MessageId, message); } break; } message.MessageMetaData.RegisterSubscription(this); //in case of single subscriber assignment; we add subscriber id to the message bool any = message.MessageMetaData.DeliveryOption == Runtime.Caching.DeliveryOption.Any || message.MessageMetaData.SubscriptionType == Common.Enum.SubscriptionType.Publisher; if (any && subscription != null) { message.MessageMetaData.AddRecepient(subscription.ID); message.MessageMetaData.AddToRecepientList(subscriptionIdentifier); } } return(true); }
public void OnSubscritionRefresh(SubscriptionIdentifier subscriptionId) { Subscriptions subscriptions; if (_subscriptions.TryGetValue(subscriptionId, out subscriptions)) { subscriptions.ResetExpiration(); } }
public bool AddSubscription(SubscriptionInfo subscriptionInfo, SubscriptionIdentifier subscriptionIdentifier, bool isUserOperation = true) { Subscriptions subscription; bool created = true; lock (_mutex) { if (_subscriptions.TryGetValue(subscriptionIdentifier, out subscription)) { if (subscription.SubscriptionPolicyType == SubscriptionPolicyType.NonDurableExclusiveSubscription && isUserOperation) { created = false; } else { if (subscriptionInfo.SubPolicyType != SubscriptionPolicyType.NonDurableExclusiveSubscription) { created = subscription.AddSubscriber(subscriptionInfo.ClientId); } } } else { switch (subscriptionInfo.SubPolicyType) { case SubscriptionPolicyType.NonDurableExclusiveSubscription: FeatureUsageCollector.Instance.GetFeature(FeatureEnum.data_sharing).UpdateUsageTime(); FeatureUsageCollector.Instance.GetFeature(FeatureEnum.pubsub, FeatureEnum.data_sharing).UpdateUsageTime(); FeatureUsageCollector.Instance.GetFeature(FeatureEnum.non_durable_subscription, FeatureEnum.pubsub).UpdateUsageTime(); if (subscriptionInfo.Type != SubscriptionType.Publisher) { subscription = new ExclusiveSubscriptions(subscriptionInfo.ClientId, subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType, subscriptionInfo.Expiration, _context); } else { subscription = new ExclusiveSubscriptions(subscriptionInfo.ClientId, subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType, subscriptionInfo.Expiration, _context, subscriptionInfo.Type); FeatureUsageCollector.Instance.GetFeature(FeatureEnum.data_sharing).UpdateUsageTime(); FeatureUsageCollector.Instance.GetFeature(FeatureEnum.pubsub, FeatureEnum.data_sharing).UpdateUsageTime(); FeatureUsageCollector.Instance.GetFeature(FeatureEnum.delivery_failure_notificatiion, FeatureEnum.pubsub).UpdateUsageTime(); } break; case SubscriptionPolicyType.EventSubscription: subscription = new EventSubscriptions(subscriptionInfo.ClientId, subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType, subscriptionInfo.Expiration, _context, subscriptionInfo.Type); break; } _subscriptions.Add(subscriptionIdentifier, subscription); } return(created); } }
/// <summary> /// Unsubscribe topic /// </summary> /// <param name="connectionId">The SignalR connectionID associated with this subscription.</param> /// <param name="topic">The topic, without filter, with nnt: qualifier, if applicable.</param> /// <param name="filter">The filter, in SQL-92 format.</param> /// <returns></returns> public async Task Unsubscribe(string connectionId, string topic, string filter) { await _subscriptionMutex.WaitAsync(); Trace.TraceVerbose("Unsubscribe. Entered monitor. ConnectionId={0} Topic={1} Filter={2}", connectionId, topic, filter); try { List <string> subscribedSelectors; if (_subscribedSelectorsForConnection.TryGetValue(connectionId, out subscribedSelectors)) { var subscription = new SubscriptionIdentifier(topic, filter); await MessageBus.Unsubscribe(topic, filter); _counters.NumberOfSubscriptionsTotal.Decrement(); Trace.TraceVerbose("Unsubscribe. MessageBus unsubscribed. ConnectionId={0} Topic={1} Filter={2}", connectionId, topic, filter); subscribedSelectors.Remove(subscription.Selector); if (subscribedSelectors.Count == 0) { _subscribedSelectorsForConnection.TryRemove(connectionId, out subscribedSelectors); } await Groups.Remove(connectionId, subscription.Selector); Trace.TraceVerbose("Unsubscribe. Group removed. ConnectionId={0} Topic={1} Filter={2}", connectionId, topic, filter); // if it's the last topic, clean up resource } } catch (AggregateException agx) { agx.Handle((e) => { Trace.TraceError(e); return(false); }); } catch (Exception ex) { Trace.TraceError(ex); throw; } finally { Trace.TraceVerbose("Unsubscribe. Releasing monitor. ConnectionId={0} Topic={1} Filter={2}", connectionId, topic, filter); _subscriptionMutex.Release(); Trace.TraceVerbose("Unsubscribe. Released monitor. ConnectionId={0} Topic={1} Filter={2}", connectionId, topic, filter); } }
public void Test_tostring() { // Arrange var identifier = new SubscriptionIdentifier("foo", @"{ ""LHS"": ""Foo"", ""OP"": ""EQ"", ""RHS"": 5 }"); // Assert Assert.That(identifier.ToString() == identifier.Selector); }
public void Test_constructor_equals_false_on_wrong_type() { // Arrange var identifier = new SubscriptionIdentifier("foo", @"{ ""LHS"": ""Foo"", ""OP"": ""EQ"", ""RHS"": 5 }"); // Assert Assert.That(identifier, Is.Not.EqualTo("kittens")); }
public void Test_that_equals_returns_false_for_kittens() { // Arrange var identifier = new SubscriptionIdentifier("foo", @"{ ""LHS"": ""Foo"", ""OP"": ""EQ"", ""RHS"": 5 }"); var kitten = "meow"; // Assert Assert.That(identifier, Is.Not.EqualTo(kitten)); // We have shown that a subscription identifier is not a kitten! }
internal ITopicSubscription RegisterSubscriptions(string subscriptionName, MessageReceivedCallback onMessageReceivedCallback, SubscriptionPolicyType subscriptionPolicy = SubscriptionPolicyType.NonDurableExclusiveSubscription, TimeSpan?timeSpan = default(TimeSpan?)) { try { _readerWriterLock.AcquireReaderLock(Timeout.Infinite); SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionName, subscriptionPolicy); TopicSubscription topicSubscription = GetExistingSubscription(subscriptionIdentifier, subscriptionPolicy); if (topicSubscription == null) { topicSubscription = new TopicSubscription(this, subscriptionName, subscriptionPolicy, onMessageReceivedCallback); DateTime creationTime = DateTime.Now; topicSubscription.CreationTime = creationTime.Ticks; topicSubscription.SetSubscriptionPolicy(subscriptionPolicy); if (timeSpan == null) { topicSubscription.Expiration = TimeSpan.MaxValue.Ticks; } else { topicSubscription.Expiration = timeSpan.Value.Ticks; } Subscribe(topicSubscription, subscriptionPolicy); lock (_subscriptions) { var existingSubscription = GetExistingSubscription(subscriptionIdentifier, subscriptionPolicy); if (existingSubscription == null) { _subscriptions.Add(subscriptionIdentifier, topicSubscription); } else { return(existingSubscription); } } _parent.OnSubscriptionCreated(this, topicSubscription); } return(topicSubscription); } finally { _readerWriterLock.ReleaseReaderLock(); } }
public void Test_properties_from_selector_constructor() { // Arrange string filter = @"{ ""LHS"": ""Foo"", ""OP"": ""EQ"", ""RHS"": ""bar"" }"; var identifier = new SubscriptionIdentifier("foo", filter); // Assert Assert.That(identifier.Topic, Is.EqualTo("foo")); Assert.That(identifier.Filter, Is.EqualTo(filter)); Assert.That(identifier.Selector, Is.EqualTo("Topic = 'foo' and " + filter)); }
private TopicSubscription GetExistingSubscription(SubscriptionIdentifier subscriptionIdentifier, SubscriptionPolicyType subscriptionPolicy) { TopicSubscription topicSubscription = null; if (_subscriptions.TryGetValue(subscriptionIdentifier, out topicSubscription)) { if ((subscriptionPolicy != SubscriptionPolicyType.EventSubscription)) { throw new OperationFailedException(ErrorCodes.PubSub.SUBSCRIPTION_EXISTS, ErrorMessages.GetErrorMessage(ErrorCodes.PubSub.SUBSCRIPTION_EXISTS)); } else { topicSubscription.UpdateCount(); } } return(topicSubscription); }
public async void Test_filter_doesnt_match() { // Arrange _mockFilterFactory.Setup(f => f.GetExpressionAsync("Topic = 'bar'")) .Returns(() => Task.FromResult(Mock.Of <IFilterExpression>(e => e.EvaluateAsync(It.IsAny <IReadOnlyDictionary <string, object> >()) == Task.FromResult <IComparable>(false)))); var subscription = new SubscriptionIdentifier("bar", null); var subscriptions = new[] { new KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate>(subscription, (topic, filter, message) => { }) }; // Act var filterTask = await _filteringService.Filter(_messageContextMock.Object, subscriptions); // Assert Assert.That(filterTask.Any(p => p.Key == subscription), Is.False); }
public bool AddSubscription(SubscriptionInfo subscriptionInfo, SubscriptionIdentifier subscriptionIdentifier, bool isUserOperation = true) { Subscriptions subscription; bool created = true; lock (_mutex) { if (_subscriptions.TryGetValue(subscriptionIdentifier, out subscription)) { if (subscription.SubscriptionPolicyType == SubscriptionPolicyType.NonDurableExclusiveSubscription && isUserOperation) { created = false; } else { if (subscriptionInfo.SubPolicyType != SubscriptionPolicyType.NonDurableExclusiveSubscription) { created = subscription.AddSubscriber(subscriptionInfo.ClientId); } } } else { switch (subscriptionInfo.SubPolicyType) { case SubscriptionPolicyType.NonDurableExclusiveSubscription: if (subscriptionInfo.Type != SubscriptionType.Publisher) { subscription = new ExclusiveSubscriptions(subscriptionInfo.ClientId, subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType, subscriptionInfo.Expiration, _context); } else { subscription = new ExclusiveSubscriptions(subscriptionInfo.ClientId, subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType, subscriptionInfo.Expiration, _context, subscriptionInfo.Type); } break; case SubscriptionPolicyType.EventSubscription: subscription = new EventSubscriptions(subscriptionInfo.ClientId, subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType, subscriptionInfo.Expiration, _context, subscriptionInfo.Type); break; } _subscriptions.Add(subscriptionIdentifier, subscription); } return(created); } }
public void Test_when_concurrent_subscribe_on_same_topic_should_callback_once() { //Arrange var count = 0; var manualResets = Enumerable.Range(0, 10).Select(_ => new ManualResetEvent(false)).ToArray(); var subscription = new SubscriptionIdentifier("foo", null); var testCallbackDelegates = new MessageBusCallbackDelegate[10]; for (int i = 0; i < 10; i++) { testCallbackDelegates[i] = (topic, filter, message) => { Interlocked.Increment(ref count); manualResets[i].Set(); } } ; var mockMessage = new Mock <IMagicHubMessage>(); _mockFilteringService .Setup(f => f.Filter( It.IsAny <IReadOnlyDictionary <string, object> >(), It.IsAny <IEnumerable <KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate> > >())) .Returns(Task.FromResult <IEnumerable <KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate> > >(new[] { new KeyValuePair <SubscriptionIdentifier, MessageBusCallbackDelegate>( subscription, (topic, filter, message) => Interlocked.Increment(ref count)) })); //Act Enumerable.Range(0, 10).AsParallel().ForAll(i => _dispatcher.Subscribe(subscription, testCallbackDelegates[i])); _dispatcher.DispatchMessage(mockMessage.Object); WaitHandle.WaitAny(manualResets, 100); //Assert Assert.That(count, Is.EqualTo(1)); } }
public void RevokeAssignment(MessageInfo messageInfo, SubscriptionInfo subscriptionInfo) { bool messageRequed = false; ClientSubscriptionManager client = null; lock (_mutex) { Message message = null; if (!_messages.TryGetValue(messageInfo.MessageId, out message)) { return; } if (subscriptionInfo == null) //revoke all subscriptions { message.MessageMetaData.RevokeSubscriptions(); } else { if (_subscribers.TryGetValue(subscriptionInfo.ClientId, out client)) { message.MessageMetaData.RevokeSubscriptions(client); } } SubscriptionIdentifier subscriptonId = null; if (subscriptionInfo != null) { subscriptonId = new SubscriptionIdentifier(); subscriptonId.SubscriptionName = subscriptionInfo.SubscriptionId; subscriptonId.SubscriptionPolicy = subscriptionInfo.SubPolicyType; } messageRequed = RequeMessage(message, subscriptonId); } if (messageRequed && _listener != null) { _listener.OnMessageArrived(this); } }
public SubscriptionInfo GetSubscriberForAssignment(SubscriptionType type, OperationContext context) { lock (_mutex) { if (_subscriptionLoadBalancer.IsValid) { SubscriptionIdentifier firstSelectedIdentifier = null; SubscriptionIdentifier selectedIdentifier = null; Subscriptions subscription; SubscriptionInfo subscriptionInfo = new SubscriptionInfo(); while (true) { selectedIdentifier = _subscriptionLoadBalancer.GetNext(); if (firstSelectedIdentifier != null && selectedIdentifier.Equals(firstSelectedIdentifier)) { return(null); } if (firstSelectedIdentifier == null) { firstSelectedIdentifier = selectedIdentifier; } if (_subscriptions.TryGetValue(selectedIdentifier, out subscription)) { if (subscription.GetSubscriptionType == type) { subscriptionInfo.ClientId = GetActiveSubscriber(subscription); subscriptionInfo.SubscriptionId = selectedIdentifier.SubscriptionName; subscriptionInfo.SubPolicyType = subscription.SubscriptionPolicyType; subscriptionInfo.Type = type; return(subscriptionInfo); } } } } return(null); } }
void RemoveSubscribers(SubscriptionIdentifier subscriptionIdentifier) { Subscriptions subscriptions; SubscriptionInfo subscriptionInfo = new SubscriptionInfo(); if (_subscriptions.TryGetValue(subscriptionIdentifier, out subscriptions)) { List <string> subscriberList = subscriptions.GetSubscriberList(); if (subscriberList.Count > 0 && subscriberList != null) { subscriptionInfo.SubscriptionId = subscriptionIdentifier.SubscriptionName; subscriptionInfo.SubPolicyType = subscriptionIdentifier.SubscriptionPolicy; subscriptionInfo.Type = SubscriptionType.Subscriber; foreach (var clientId in subscriberList) { subscriptionInfo.ClientId = clientId; UnSubscribeSubscription(subscriptionInfo); } } } }
public void OnSubscriptonRemoved(Message message, SubscriptionInfo subscriptionInfo) { bool messageRequed = false; SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); HashSet <SubscriptionIdentifier> subscriptionIdentifierList = new HashSet <SubscriptionIdentifier>(); lock (_mutex) { message.MessageMetaData.RemoveFromReciepientList(subscriptionIdentifier); if (!_messages.TryGetValue(message.MessageId, out message)) { return; } messageRequed = RequeMessage(message, subscriptionIdentifier); } if (messageRequed && _listener != null) { _listener.OnMessageArrived(this); } }
public void AddSubscription(SubscriptionInfo subscriptionInfo) { if (String.Compare(subscriptionInfo.ClientId, ClientID, StringComparison.OrdinalIgnoreCase) != 0) { return; } SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); lock (this) { _lastActivityTime = _updateTime = DateTime.Now; switch (subscriptionInfo.Type) { //add subscriptionIdentifier instead case Common.Enum.SubscriptionType.Subscriber: if (!_messageSubscriptions.ContainsKey(subscriptionIdentifier)) { _messageSubscriptions.Add(subscriptionIdentifier, new Subscribers(subscriptionInfo.SubscriptionId, subscriptionInfo.Type)); _messageSubscriptionLoadbalancer.Add(subscriptionIdentifier); if (subscriptionInfo.ExpirationCheck()) { _refreshSubscriptions.Add(subscriptionIdentifier); } } break; case Common.Enum.SubscriptionType.Publisher: if (!_deliverySubscriptions.ContainsKey(subscriptionIdentifier)) { _deliverySubscriptions.Add(subscriptionIdentifier, new Subscribers(subscriptionInfo.SubscriptionId, subscriptionInfo.Type)); _deliverSubscriptionLoadbalancer.Add(subscriptionIdentifier); } break; } } }
/// <summary> /// Unsubscribe all topics for connection /// </summary> /// <param name="connectionId">SignallR connection for which to unsubscribe</param> public async Task Unsubscribe(string connectionId) { await _subscriptionMutex.WaitAsync(); Trace.TraceVerbose("Unsubscribe all. Entered Monitor. ConnectionId={0}", connectionId); try { List <string> selectorsToUnsubscribe; if (_subscribedSelectorsForConnection.TryRemove(connectionId, out selectorsToUnsubscribe)) { Trace.TraceVerbose("Unsubscribe all Removing all groups. ConnectionId={0}", connectionId); foreach (var selector in selectorsToUnsubscribe) { var subscription = new SubscriptionIdentifier(selector); await _messageBus.Unsubscribe(subscription.Topic, subscription.Filter); _counters.NumberOfSubscriptionsTotal.Decrement(); Groups.Remove(connectionId, selector); } //await Task.WhenAll( // selectorsToUnsubscribe.Select((selector) => Groups.Remove(connectionId, selector))); Trace.TraceVerbose("Unsubscribe all removed all groups. ConnectionId={0}", connectionId); } } catch (Exception exception) { //eat the exception as unsubscribe for connectionid need not be propogated as client is already disconnected. Trace.TraceError(exception); } finally { _subscriptionMutex.Release(); Trace.TraceVerbose("Unsubscribe all released monitor. ConnectionId={0}", connectionId); } }
private bool AssignMessageToAllSubscriptions(SubscriptionInfo subscriptionInfo, Message message) { bool assigned = false; Subscriptions subscriptions; ClientSubscriptionManager clientManager; lock (_mutex) { if (subscriptionInfo.SubPolicyType != SubscriptionPolicyType.EventSubscription) { foreach (var subscription in _subscriptions) { HashSet <SubscriptionIdentifier> subscriptionIdentifierList; if (subscription.Value.IsActive() && subscription.Value.SubscriptionPolicyType == SubscriptionPolicyType.NonDurableExclusiveSubscription) { string clientId = subscription.Value.GetSubscriber(); if (!String.IsNullOrEmpty(clientId)) { if (_subscribers.TryGetValue(clientId, out clientManager)) { if (clientManager.HasMessageSubscriptons(SubscriptionType.Subscriber)) { assigned |= clientManager.AssignMessageToSubscription(message, subscriptionInfo); } } } } } } else { if (message.IsMulticast) { MultiCastMessage multicastMessage = (MultiCastMessage)message; if (multicastMessage.SpecificReciepients.Count > 0 || multicastMessage.SpecificReciepients != null) { List <SubscriptionInfo> subinfolist = multicastMessage.SpecificReciepients; foreach (var subInfo in subinfolist) { if (_subscribers.TryGetValue(subInfo.ClientId, out clientManager)) { assigned = clientManager.AssignMessageToSubscription(message, subscriptionInfo); } } } } else { SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(); subscriptionIdentifier.SubscriptionName = SubscriptionInfo.EventsSubscriptionName; subscriptionIdentifier.SubscriptionPolicy = SubscriptionPolicyType.EventSubscription; if (_subscriptions.TryGetValue(subscriptionIdentifier, out subscriptions)) { List <string> subscribedClients = subscriptions.GetSubscriberList(); if (subscriptions.IsActive() && (subscribedClients.Count > 0)) { foreach (var clientId in subscribedClients) { if (_subscribers.TryGetValue(clientId, out clientManager)) { if (clientManager.HasMessageSubscriptons(SubscriptionType.Subscriber)) { assigned |= clientManager.AssignMessageToSubscription(message, subscriptionInfo); } } } } } } } } return(assigned); }
public bool RemoveSubscription(SubscriptionInfo subscriptionInfo) { //use subscription IDentifier if (string.Compare(subscriptionInfo.ClientId, ClientID, true) != 0) { return(false); } SubscriptionIdentifier subscriptionIdentifier = new SubscriptionIdentifier(subscriptionInfo.SubscriptionId, subscriptionInfo.SubPolicyType); List <Message> removedMessages = new List <Message>(); bool result = false; lock (this) { _lastActivityTime = _updateTime = DateTime.Now; switch (subscriptionInfo.Type) { case Common.Enum.SubscriptionType.Subscriber: if (_messageSubscriptions.ContainsKey(subscriptionIdentifier)) { result = _messageSubscriptions.Remove(subscriptionIdentifier); _messageSubscriptionLoadbalancer.Remove(subscriptionIdentifier); } break; case Common.Enum.SubscriptionType.Publisher: if (_deliverySubscriptions.ContainsKey(subscriptionIdentifier)) { result = _deliverySubscriptions.Remove(subscriptionIdentifier); _deliverSubscriptionLoadbalancer.Remove(subscriptionIdentifier); } break; } foreach (Message message in _messages.Values) { if (message.MessageMetaData.DeliveryOption == Runtime.Caching.DeliveryOption.Any) { message.MessageMetaData.RemoveRecepient(subscriptionInfo.SubscriptionId); message.MessageMetaData.RemoveFromReciepientList(subscriptionIdentifier); } message.MessageMetaData.UnregisterSubscription(this); if (message.MessageMetaData.IsRemovable) { removedMessages.Add(message); } } foreach (Message message in _delivryNotificationMessages.Values) { message.MessageMetaData.UnregisterSubscription(this); message.MessageMetaData.RemoveRecepient(subscriptionInfo.SubscriptionId); message.MessageMetaData.RemoveFromReciepientList(subscriptionIdentifier); if (message.MessageMetaData.IsRemovable) { removedMessages.Add(message); } } } foreach (Message message in removedMessages) { if (message.MessageMetaData.SubscriptionType == Common.Enum.SubscriptionType.Publisher) { _delivryNotificationMessages.Remove(message.MessageId); } else { _messages.Remove(message.MessageId); } _topic.OnSubscriptonRemoved(message, subscriptionInfo); } _refreshSubscriptions.Remove(subscriptionIdentifier); return(result); }