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(); } }
internal void UnSubscribeEventTopic(TopicSubscription subscription, bool remove = false) { try { _readerWriterLock.AcquireReaderLock(Timeout.Infinite); UnSubscribe(subscription, remove); _eventRegistered = false; } finally { _readerWriterLock.ReleaseReaderLock(); } }
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(); } }
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); }
internal void Subscribe(TopicSubscription subscription, SubscriptionPolicyType subscriptionPolicy = SubscriptionPolicyType.NonDurableExclusiveSubscription) { try { _readerWriterLock.AcquireReaderLock(Timeout.Infinite); if (_isDisposed) { return; } _cacheImpl.Subscribe(Name, subscription.SubscriptionName, SubscriptionType.Subscriber, subscription.CreationTime, subscription.Expiration, subscriptionPolicy); } finally { _readerWriterLock.ReleaseReaderLock(); } }
/// <summary> /// Unregisters CacheDataNotificationCallback /// <para>Flag based unregistration</para> /// </summary> /// <param name="callback"></param> /// <param name="key"></param> /// <param name="eventType"></param> internal short[] UnregisterSelectiveNotification(CacheDataNotificationCallback callback, EventTypeInternal eventType) { if (callback == null) { return(null); } short[] returnValue = new short[] { -1, -1 }; //First value update callback ref & sencond is remove callbackref foreach (EventTypeInternal type in Enum.GetValues(typeof(EventTypeInternal))) { if (type == EventTypeInternal.ItemAdded) //ItemAdded not supported Yet { continue; } object id = -1; lock (SyncLockSelective) { ResourcePool pool = null; ResourcePool poolID = null; #region pool selection if (type == EventTypeInternal.ItemRemoved && (eventType & EventTypeInternal.ItemRemoved) != 0) { pool = _selectiveRemoveEventPool; poolID = _selectiveRemoveEventIDPool; if (pool == null) { removeCallbacks = 0; } } else if (type == EventTypeInternal.ItemUpdated && (eventType & EventTypeInternal.ItemUpdated) != 0) { pool = _selectiveUpdateEventPool; poolID = _selectiveUpdateEventIDPool; if (pool == null) { updateCallbacks = 0; } } if (removeCallbacks == 0 && updateCallbacks == 0) { _selectiveEventsSubscription.UnSubscribeEventTopic(); _selectiveEventsSubscription = null; } if (pool == null) { continue; } #endregion int i = type == EventTypeInternal.ItemUpdated ? 0 : 1; id = pool.GetResource(callback); if (id is short) { returnValue[i] = (short)id; } } } return(returnValue); }
/// <summary> /// Returning Negative value means operation not successfull /// </summary> /// <param name="discriptor"></param> /// <param name="eventType"></param> /// <returns>short array <para>1st value is Update callbackRef</para> <para>nd value is removeRef</para></returns> private short[] RegisterSelectiveDiscriptor(CacheDataNotificationCallback callback, EventTypeInternal eventType, CallbackType callbackType) { if (callback == null) { return(null); //FAIL CONDITION } short[] returnValue = new short[] { -1, -1 }; //First value update callback ref & sencond is remove callbackref foreach (EventTypeInternal type in Enum.GetValues(typeof(EventTypeInternal))) { if (type == EventTypeInternal.ItemAdded) //ItemAdded not supported Yet { continue; } lock (SyncLockSelective) { ResourcePool pool = null; ResourcePool poolID = null; #region pool selection if (type == EventTypeInternal.ItemRemoved && (eventType & EventTypeInternal.ItemRemoved) != 0) { pool = _selectiveRemoveEventPool; poolID = _selectiveRemoveEventIDPool; } else if (type == EventTypeInternal.ItemUpdated && (eventType & EventTypeInternal.ItemUpdated) != 0) { pool = _selectiveUpdateEventPool; poolID = _selectiveUpdateEventIDPool; } if (pool == null) { continue; } #endregion while (true) { int i = type == EventTypeInternal.ItemUpdated ? 0 : 1; if (pool.GetResource(callback) == null) { returnValue[i] = type == EventTypeInternal.ItemUpdated ? ++_selectiveUpdateCallbackRef : ++_selectveRemoveCallbackRef; pool.AddResource(callback, returnValue[i]); poolID.AddResource(returnValue[i], callback); break; } else { try { short cref = (short)pool.GetResource(callback); if (cref < 0) { break; //FAIL CONDITION } //add it again into the table for updating ref count. pool.AddResource(callback, cref); poolID.AddResource(cref, callback); returnValue[i] = cref; break; } catch (NullReferenceException) { //Legacy code: can create an infinite loop //Recomendation of returning a negative number instead of continue continue; } } } } } if (_selectiveEventsSubscription == null && callbackType != CallbackType.PullBasedCallback) { Topic topic = (Topic)_cache._messagingService.GetTopic(TopicConstant.ItemLevelEventsTopic, true); _selectiveEventsSubscription = (TopicSubscription)topic.CreateEventSubscription(OnSelectiveEventMessageReceived); } return(returnValue); }
internal void OnSubscriptionCreated(Topic topic, TopicSubscription topicSubscription) { StartPolling(); }