Пример #1
0
        /// <summary>
        /// TheadSafe and no locks internally
        /// </summary>
        /// <param name="key"></param>
        /// <param name="eventType">Should contain one type i.e. should not be used as a flag.
        /// Every EventType should be executed from another thread</param>
        /// <param name="item"></param>
        /// <param name="oldItem"></param>
        /// <param name="reason"></param>
        /// <param name="notifyAsync"></param>
        internal void RaiseGeneralCacheNotification(string key, EventType eventType, EventCacheItem item,
                                                    EventCacheItem oldItem, CacheItemRemovedReason reason, bool notifyAsync)
        {
            try
            {
                object[] registeredDiscriptors = null;

                ResourcePool eventPool = GetEventPool(eventType);
                if (eventPool != null)
                {
                    registeredDiscriptors = eventPool.GetAllResourceKeys();
                }

                if (registeredDiscriptors != null && registeredDiscriptors.Length > 0)
                {
                    for (int i = 0; i < registeredDiscriptors.Length; i++)
                    {
                        CacheEventDescriptor discriptor = registeredDiscriptors[i] as CacheEventDescriptor;

                        if (discriptor == null)
                        {
                            continue;
                        }

                        var arg = CreateCacheEventArgument(discriptor.DataFilter, key, _cacheName, eventType, item, oldItem,
                                                           reason);
                        arg.Descriptor = discriptor;

                        if (notifyAsync)
                        {
#if !NETCORE
                            discriptor.CacheDataNotificationCallback.BeginInvoke(key, arg, asyn, null);
#elif NETCORE
                            TaskFactory factory = new TaskFactory();
                            Task        task    = factory.StartNew(() => discriptor.CacheDataNotificationCallback(key, arg));
#endif
                        }
                        else
                        {
                            discriptor.CacheDataNotificationCallback.Invoke(key, arg);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (_logger != null && _logger.IsErrorEnabled)
                {
                    _logger.CriticalInfo(ex.ToString());
                }
            }
        }
Пример #2
0
        internal EventHandle UnregisterDiscriptor(CacheEventDescriptor discriptor)
        {
            if (discriptor == null || !discriptor.IsRegistered)
            {
                return(null);
            }

            foreach (EventType type in Enum.GetValues(typeof(EventType)))
            {
                ResourcePool pool = null;

                #region Pool selection

                if ((type & discriptor.RegisteredAgainst) != 0)
                {
                    pool = GetEventPool(EventsUtil.GetEventTypeInternal(type));
                }

                if (pool == null)
                {
                    continue;
                }
                #endregion

                short           registrationSequenceId = -1;
                bool            unregisterNotification = false;
                EventDataFilter maxDataFilter          = EventDataFilter.None;

                lock (SyncLockGeneral)
                {
                    object retVal = pool.RemoveResource(discriptor);

                    if (retVal == null)
                    {
                        continue;
                    }
                    unregisterNotification = pool.Count == 0;

                    if (!unregisterNotification)
                    {
                        object[] pooledDescriptors = pool.GetAllResourceKeys();

                        if (pooledDescriptors != null)
                        {
                            for (int i = 0; i < pooledDescriptors.Length; i++)
                            {
                                CacheEventDescriptor pooledDescriptor = pooledDescriptors[i] as CacheEventDescriptor;

                                if (pooledDescriptor.DataFilter > maxDataFilter)
                                {
                                    maxDataFilter = pooledDescriptor.DataFilter;
                                }
                            }
                        }
                    }


                    discriptor.IsRegistered = false;

                    //keeps a sequence number
                    switch (type)
                    {
                    case EventType.ItemAdded:
                        //Data filter is being updated
                        if (maxDataFilter != _generalAddDataFilter)
                        {
                            _generalAddDataFilter  = maxDataFilter;
                            registrationSequenceId = ++_addEventRegistrationSequence;
                        }
                        if (unregisterNotification)
                        {
                            _generalAddDataFilter = EventDataFilter.None;
                        }
                        break;

                    case EventType.ItemRemoved:
                        if (maxDataFilter != _generalRemoveDataFilter)
                        {
                            _generalRemoveDataFilter = maxDataFilter;
                            registrationSequenceId   = ++_removeEventRegistrationSequenceId;
                        }
                        if (unregisterNotification)
                        {
                            _generalAddDataFilter = EventDataFilter.None;
                        }
                        break;

                    case EventType.ItemUpdated:
                        if (maxDataFilter != _generalUpdateDataFilter)
                        {
                            _generalUpdateDataFilter = maxDataFilter;
                            registrationSequenceId   = ++_updateEventRegisrationSequenceId;
                        }
                        if (unregisterNotification)
                        {
                            _generalAddDataFilter = EventDataFilter.None;
                        }

                        break;
                    }
                }

                if (_cache != null)
                {
                    if (unregisterNotification)
                    {
                        //client is no more interested in event, therefore unregister it from server
                        _cache.UnregiserGeneralCacheNotification(EventsUtil.GetEventTypeInternal(type));
                    }
                    else if (registrationSequenceId != -1)
                    {
                        //only caused update of data filter either upgrade or downgrade
                        _cache.RegisterCacheNotificationDataFilter(EventsUtil.GetEventTypeInternal(type), maxDataFilter, registrationSequenceId);
                    }
                }
            }
            return(null);
        }
Пример #3
0
        /// <summary>
        /// TheadSafe and no locks internally
        /// </summary>
        /// <param name="key"></param>
        /// <param name="eventType">Should contain one type i.e. should not be used as a flag.
        /// Every EventType should be executed from another thread</param>
        /// <param name="item"></param>
        /// <param name="oldItem"></param>
        /// <param name="reason"></param>
        /// <param name="notifyAsync"></param>
        internal void RaiseGeneralCacheNotification(string key, EventType eventType, EventCacheItem item, EventCacheItem oldItem, CacheItemRemovedReason reason, bool notifyAsync)
        {
            try
            {
                object[] registeredDiscriptors = null;

                ResourcePool eventPool = GetEventPool(EventsUtil.GetEventTypeInternal(eventType));
                if (eventPool != null)
                {
                    registeredDiscriptors = eventPool.GetAllResourceKeys();
                }

                if (registeredDiscriptors != null && registeredDiscriptors.Length > 0)
                {
                    for (int i = 0; i < registeredDiscriptors.Length; i++)
                    {
                        CacheEventDescriptor discriptor = registeredDiscriptors[i] as CacheEventDescriptor;

                        if (discriptor == null)
                        {
                            continue;
                        }

                        var bitSet = new BitSet();

                        if (_cache.SerializationFormat == Common.Enum.SerializationFormat.Json)
                        {
                            bitSet.SetBit(BitSetConstants.JsonData);
                        }

                        if (item != null)
                        {
                            item.SetValue(_cache.SafeDeserialize <object>(item.GetValue <object>(), _cache.SerializationContext, bitSet, UserObjectType.CacheItem));
                        }

                        if (oldItem != null)
                        {
                            oldItem.SetValue(_cache.SafeDeserialize <object>(oldItem.GetValue <object>(), _cache.SerializationContext, bitSet, UserObjectType.CacheItem));
                        }

                        var arg = CreateCacheEventArgument(discriptor.DataFilter, key, _cacheName, eventType, item, oldItem, reason);
                        arg.Descriptor = discriptor;

                        if (notifyAsync)
                        {
#if !NETCORE
                            discriptor.CacheDataNotificationCallback.BeginInvoke(key, arg, asyn, null);
#elif NETCORE
                            //TODO: ALACHISOFT (BeginInvoke is not supported in .Net Core thus using TaskFactory)
                            TaskFactory factory = new TaskFactory();
                            Task        task    = factory.StartNew(() => discriptor.CacheDataNotificationCallback(key, arg));
#endif
                        }
                        else
                        {
                            discriptor.CacheDataNotificationCallback.Invoke(key, arg);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (_logger != null && _logger.IsErrorEnabled)
                {
                    _logger.CriticalInfo(ex.ToString());
                }
            }
        }
Пример #4
0
        /// <summary>
        /// This method Unregisters a custom callback that is fired on change in dataset of a continous query
        /// </summary>
        /// <param name="callback">A delegate to register your custom method with</param>
        /// <param name="eventType">Describes whether the event is to be raised on Item Added, Updated or Removed</param>
        /// <example>
        /// Lets consider we created an ItemCallback
        /// <code>
        /// ItemCallback(string key, CacheEventArg e)
        /// {
        ///    ...
        /// }
        /// </code>
        /// Uregister your notification callback
        /// <code>
        /// cQ.RegisterNotification(new QueryDataNotificationCallback(ItemCallback),EventType.ItemAdded);
        /// </code>
        /// </example>
        public void UnRegisterNotification(QueryDataNotificationCallback callback, EventType eventType)
        {
            //BY LEGACY DESIGN THERE IS NO UNREGISTRATION PROCESS

            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            object id = -1;

            foreach (EventType type in Enum.GetValues(typeof(EventType)))
            {
                lock (syncLock)
                {
                    ResourcePool pool   = null;
                    ResourcePool poolDF = null;

                    #region pool selection

                    if (type == EventType.ItemAdded && (eventType & EventType.ItemAdded) != 0)
                    {
                        pool   = _cqAddEventPool;
                        poolDF = _cqAddEventDataFilter;
                    }
                    else if (type == EventType.ItemRemoved && (eventType & EventType.ItemRemoved) != 0)
                    {
                        pool   = _cqRemoveEventPool;
                        poolDF = _cqRemoveEventDataFilter;
                    }
                    else if (type == EventType.ItemUpdated && (eventType & EventType.ItemUpdated) != 0)
                    {
                        pool   = _cqUpdateEventPool;
                        poolDF = _cqUpdateEventDataFilter;
                    }

                    if (pool == null)
                    {
                        continue;
                    }

                    #endregion

                    object temp  = pool.GetResource(callback);
                    short  index = -1;
                    index = Convert.ToInt16(temp);


                    if (index > -1)
                    {
                        EventDataFilter datafilter = (EventDataFilter)poolDF.GetResource(index);

                        object retVal = poolDF.RemoveResource(index);
                        pool.RemoveResource(callback);

                        if (retVal == null)
                        {
                            continue;
                        }
                        bool            unregisterNotification = poolDF.Count == 0;
                        EventDataFilter maxDataFilter          = EventDataFilter.None;


                        if (!unregisterNotification)
                        {
                            object[] callbackRefs = poolDF.GetAllResourceKeys();

                            if (callbackRefs != null)
                            {
                                for (int i = 0; i < callbackRefs.Length; i++)
                                {
                                    EventDataFilter df = (EventDataFilter)callbackRefs[i];

                                    if (df > maxDataFilter)
                                    {
                                        maxDataFilter = df;
                                    }

                                    if (maxDataFilter == EventDataFilter.DataWithMetadata)
                                    {
                                        break;
                                    }
                                }
                            }
                        }

                        if (type == EventType.ItemAdded)
                        {
                            _cqAddDF = maxDataFilter;
                        }
                        else if (type == EventType.ItemRemoved)
                        {
                            _cqRemoveDF = maxDataFilter;
                        }
                        else
                        {
                            _cqUpdateDF = maxDataFilter;
                        }
                    }
                }
            }
        }