public static void Main(string[] args) { try { //Initialize cache Cache cache; cache = NCache.InitializeCache("mypartitionedcache"); cache.Clear(); //See output cache.Add("Item:1", "Value:1"); //Key based notifications allows item notifications for particular //items in cache CacheDataNotificationCallback myMethod = new CacheDataNotificationCallback(KeyNotificationMethod); cache.RegisterCacheNotification("Item:1", myMethod, EventType.ItemAdded | EventType.ItemRemoved | EventType.ItemUpdated,EventDataFilter.None); //See output cache.Insert("Item:1", "Value:1-------Changed for notifications"); //See output cache.Delete("Item:1"); Console.WriteLine(); //Must dispose cache cache.Dispose(); Environment.Exit(0); } catch (Exception ex) { Console.WriteLine(ex.Message); Environment.Exit(0); } }
/// <summary> /// Registers ItemUpdate or ItemRemoved events with cache /// </summary> /// <remarks> /// Client application can show interest in receiving events if an item is update or removed from the cache. /// As soon as the item is updated or removed from the cache, the client application is notified /// and actions can be taken accordingly. /// </remarks> /// <param name="cacheDataNotificationCallback">the CacheDataNotificationCallback that is invoked when an item is added, updated or removed from the cache.</param> /// <param name="eventType">Tells whether the event is to be raised on Item Added, Updated or Removed</param> /// <param name="datafilter">Tells whether to receive metadata, data with metadata or none when a notification is triggered</param> /// <example> /// First create an ItemCallback /// <code> /// ItemCallback(string key, CacheEventArg e) /// { /// ... /// } /// </code> /// Then register the Cache Notification /// <code> /// Cache cache = NCache.InitializeCache("myCache"); /// CacheEventDescriptor descriptor=cache.RegisterCacheNotification(new CacheDataNotificationCallback(ItemCallback), EventType.ItemAdded, EventDataFilter.None); /// /// </code> /// </example> internal virtual CacheEventDescriptor RegisterCacheNotification(CacheDataNotificationCallback cacheDataNotificationCallback, EventType eventType, EventDataFilter datafilter) { if (cacheDataNotificationCallback == null) throw new ArgumentException("cacheDataNotificationCallback"); return RegisterCacheNotificationInternal(null, cacheDataNotificationCallback, eventType, datafilter, true); }
/// <summary> /// Function that choose the appropriate function of NCache's Cache, that need to be called /// according to the data provided to it.</summary> internal virtual void InsertOperation(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, LockHandle lockHandle, LockAccessType accessType, CacheDataNotificationCallback cacheItemUdpatedCallback, CacheDataNotificationCallback cacheItemRemovedCallaback, EventDataFilter itemUpdateDataFilter, EventDataFilter itemRemovedDataFilter, ref long size, bool allowQueryTags) { if (_cacheImpl == null) throw new OperationFailedException("Cache is not initialized"); ValidateKeyValue(key, value); UsageStats stats = new UsageStats(); stats.BeginSample(); Hashtable queryInfo = new Hashtable(); object lockId = (lockHandle == null) ? null : lockHandle.LockId; if (allowQueryTags) { queryInfo["query-info"] = GetQueryInfo(value); } short removeCallbackId = -1; short updateCallbackId = -1; short dsItemUpdateCallbackId = -1; BitSet flagMap = new BitSet(); try { value = SafeSerialize(value, _serializationContext, ref flagMap, ref size); long objectSize = 0; if (DebugAPIConfiguraions.LoggingEnabled) objectSize = value is byte[] ? ((byte[])value).Length : 0; if (_perfStatsCollector != null && value != null && value is byte[]) _perfStatsCollector.IncrementAvgItemSize(((byte[])value).Length); if (cacheItemRemovedCallaback != null) { short[] callabackIds = _eventManager.RegisterSelectiveEvent(cacheItemRemovedCallaback, EventType.ItemRemoved, itemRemovedDataFilter); removeCallbackId = callabackIds[1]; } if (cacheItemUdpatedCallback != null) { short[] callabackIds = _eventManager.RegisterSelectiveEvent(cacheItemUdpatedCallback, EventType.ItemUpdated, itemUpdateDataFilter); updateCallbackId = callabackIds[0]; } if (lockId != null && ((string)lockId) != string.Empty) flagMap.SetBit(BitSetConstants.LockedItem); else flagMap.UnsetBit(BitSetConstants.LockedItem); absoluteExpiration = ToUTC(absoluteExpiration); _cacheImpl.Insert(key, value, absoluteExpiration, slidingExpiration, priority, removeCallbackId, updateCallbackId, queryInfo, flagMap, lockId, accessType, itemUpdateDataFilter, itemRemovedDataFilter, size); if (_perfStatsCollector != null) { stats.EndSample(); _perfStatsCollector.IncrementMsecPerUpdSample(stats.Current); _perfStatsCollector.IncrementUpdPerSecStats(); } } catch (Exception) { if (ExceptionsEnabled) throw; } }
/// <summary> /// Function that choose the appropriate function of NCache's Cache, that need to be called /// according to the data provided to it.</summary> internal virtual object AddOperation(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheDataNotificationCallback cacheItemUdpatedCallback, CacheDataNotificationCallback cacheItemRemovedCallaback, EventDataFilter itemUpdateDataFilter, EventDataFilter itemRemovedDataFilter, ref long size, bool allowQueryTags) { if (_cacheImpl == null) throw new OperationFailedException("Cache is not initialized"); ValidateKeyValue(key, value); UsageStats stats = new UsageStats(); stats.BeginSample(); Hashtable queryInfo = new Hashtable(); if (allowQueryTags) { queryInfo["query-info"] = GetQueryInfo(value); } BitSet flagMap = new BitSet(); try { long objectSize = 0; value = SafeSerialize(value, _serializationContext, ref flagMap, ref size); if (DebugAPIConfiguraions.LoggingEnabled) objectSize = value is byte[] ? ((byte[])value).Length : 0; if (_perfStatsCollector != null && value != null && value is byte[]) _perfStatsCollector.IncrementAvgItemSize(((byte[])value).Length); if (DebugAPIConfiguraions.LoggingEnabled) { LogSizeInfo(false, objectSize); } short removeCallbackID = -1; short updateCallbackID = -1; if (cacheItemRemovedCallaback != null) { short[] callabackIds = _eventManager.RegisterSelectiveEvent(cacheItemRemovedCallaback, EventType.ItemRemoved, itemRemovedDataFilter); removeCallbackID = callabackIds[1]; } if (cacheItemUdpatedCallback != null) { short[] callabackIds = _eventManager.RegisterSelectiveEvent(cacheItemUdpatedCallback, EventType.ItemUpdated, itemUpdateDataFilter); updateCallbackID = callabackIds[0]; } absoluteExpiration = ToUTC(absoluteExpiration); _cacheImpl.Add(key, value, absoluteExpiration, slidingExpiration, priority, removeCallbackID, updateCallbackID, queryInfo, flagMap, itemUpdateDataFilter, itemRemovedDataFilter, size); if (_perfStatsCollector != null) { stats.EndSample(); _perfStatsCollector.IncrementMsecPerAddSample(stats.Current); _perfStatsCollector.IncrementAddPerSecStats(); } return value; } catch (Exception) { if (ExceptionsEnabled) throw; } return null; }
/// <summary> /// Unregisters event that may have been registered against a specific key /// </summary> /// <param name="key">The cache key used to reference the cache item</param> /// <param name="callback">The CacheDataNotificationCallback that was specified while registering the event.</param> /// <param name="eventType">Type of the event to unregister</param> /// <example> /// Let us consider you registered an event against a key /// <code> /// Cache cache = NCache.InitializeCache("myCache"); /// cache.RegisterCacheNotification(key, new CacheDataNotificationCallback(ItemCallback), EventType.ItemUpdated, EventDataFilter.None); /// </code> /// Now, Unregister this event by providing the key, callback and eventtype /// <code> /// cache.UnRegisterCacheNotification(key, new CacheDataNotificationCallback(ItemCallback), EventType.ItemUpdated); /// </code> /// </example> public virtual void UnRegisterCacheNotification(string key, CacheDataNotificationCallback callback, EventType eventType) { if (_cacheImpl == null) if (_cacheImpl == null) throw new OperationFailedException("Cache is not initialized"); if (key == null) throw new ArgumentNullException("key"); if (callback == null) throw new ArgumentNullException("CacheDataNotificationCallback"); try { short[] value = this._eventManager.UnregisterSelectiveNotification(callback, eventType); short update = value[0]; short remove = value[1]; _cacheImpl.UnRegisterKeyNotificationCallback(key, update, remove); } catch (Exception) { if (ExceptionsEnabled) throw; } }
/// <summary> /// Registers the ItemUpdate or ItemRemoved events for the specified key. /// </summary> /// <param name="key">The cache key used to reference the cache item.</param> /// <param name="selectiveCacheDataNotificationCallback">The CacheDataNotificationCallback that is invoked when an item is added, updated or removed from the cache.</param> /// <param name="eventType">Tells whether the event is to be raised on Item Added, Updated or Removed</param> /// <param name="datafilter">Tells whether to receive metadata, data with metadata or none when a notification is triggered</param> /// <example> /// First create an ItemCallback /// <code> /// ItemCallback(string key, CacheEventArg e) /// { /// ... /// } /// </code> /// Then register the Key Notification /// <code> /// Cache cache = NCache.InitializeCache("myCache"); /// cache.RegisterCacheNotification(key, new CacheDataNotificationCallback(ItemCallback), EventType.ItemUpdated, EventDataFilter.None); /// /// </code> /// </example> public virtual void RegisterCacheNotification(string key, CacheDataNotificationCallback selectiveCacheDataNotificationCallback, EventType eventType) { if (key == null || key.Length == 0) throw new ArgumentNullException("key"); if (selectiveCacheDataNotificationCallback == null) throw new ArgumentException("selectiveCacheDataNotificationCallback"); EventDataFilter datafilter = EventDataFilter.None; RegisterCacheNotificationInternal(key, selectiveCacheDataNotificationCallback, eventType, datafilter, true); }
//Creation is CacheDesriptor's responsiblity static internal CacheEventDescriptor CreateCacheDiscriptor(EventType eventType, string cacheName, CacheDataNotificationCallback callback, EventDataFilter datafilter) { CacheEventDescriptor descriptor = new CacheEventDescriptor(); descriptor.RegisteredAgainst = eventType; descriptor.CacheName = cacheName; descriptor.CacheDataNotificationCallback = callback; descriptor.IsRegistered = true; descriptor.DataFilter = datafilter; return(descriptor); }
/// <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, EventType eventType) { if (callback == null) return null; short[] returnValue = new short[] { -1, -1 }; //First value update callback ref & sencond is remove callbackref foreach (EventType type in Enum.GetValues(typeof(EventType))) { if (type == EventType.ItemAdded) //ItemAdded not supported Yet continue; object id = -1; lock (SyncLockSelective) { ResourcePool pool = null; ResourcePool poolID = null; #region pool selection if (type == EventType.ItemRemoved && (eventType & EventType.ItemRemoved) != 0) { pool = _selectiveRemoveEventPool; poolID = _selectiveRemoveEventIDPool; } else if (type == EventType.ItemUpdated && (eventType & EventType.ItemUpdated) != 0) { pool = _selectiveUpdateEventPool; poolID = _selectiveUpdateEventIDPool; } if (pool == null) continue; #endregion // For selective callback, we dont remove the callback as it can create chaos if user try to unregister //a callback more then one time or against wrong items. int i = type == EventType.ItemUpdated ? 0 : 1; id = pool.GetResource(callback); if (id is short) { returnValue[i] = (short)id; } } } return returnValue; }
public override void RegisterCacheNotification(string key, CacheDataNotificationCallback selectiveCacheDataNotificationCallback, Runtime.Events.EventType eventType) { string exceptionMessage = null; try { _webCache.RegisterCacheNotification(key, selectiveCacheDataNotificationCallback, eventType); } catch (Exception e) { exceptionMessage = e.Message; throw; } finally { try { if (_debugConfigurations.IsInLoggingInterval()) { APILogItem logItem = new APILogItem(); logItem.Signature = "RegisterCacheNotification(string key, CacheDataNotificationCallback selectiveCacheDataNotificationCallback, Runtime.Events.EventType eventType, Runtime.Events.EventDataFilter datafilter)"; logItem.ExceptionMessage = exceptionMessage; logItem.Key = key; _apiLogger.Log(logItem); } } catch (Exception) { } } }
internal override CacheEventDescriptor RegisterCacheNotificationInternal(string key, CacheDataNotificationCallback callback, Runtime.Events.EventType eventType, Runtime.Events.EventDataFilter datafilter, bool notifyOnItemExpiration) { return _webCache.RegisterCacheNotificationInternal(key, callback, eventType, datafilter, notifyOnItemExpiration); }
internal override CacheEventDescriptor RegisterCacheNotification(CacheDataNotificationCallback cacheDataNotificationCallback, Runtime.Events.EventType eventType, Runtime.Events.EventDataFilter datafilter) { CacheEventDescriptor result = null; string exceptionMessage = null; try { result = _webCache.RegisterCacheNotification(cacheDataNotificationCallback, eventType, datafilter); } catch (Exception e) { exceptionMessage = e.Message; throw; } finally { try { if (_debugConfigurations.IsInLoggingInterval()) { APILogItem logItem = new APILogItem(); logItem.Signature = "RegisterCacheNotification(string key, CacheDataNotificationCallback selectiveCacheDataNotificationCallback, Runtime.Events.EventType eventType, Runtime.Events.EventDataFilter datafilter)"; logItem.ExceptionMessage = exceptionMessage; _apiLogger.Log(logItem); } } catch (Exception) { } } return result; }
internal override void InsertOperation(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, LockHandle lockHandle, LockAccessType accessType, CacheDataNotificationCallback cacheItemUdpatedCallback, CacheDataNotificationCallback cacheItemRemovedCallaback, EventDataFilter itemUpdateDataFilter, EventDataFilter itemRemovedDataFilter, ref long size, bool allowQueryTags) { _webCache.InsertOperation(key, value, absoluteExpiration, slidingExpiration, priority, lockHandle, accessType, cacheItemUdpatedCallback, cacheItemRemovedCallaback, itemUpdateDataFilter, itemRemovedDataFilter, ref size, true); }
internal override void InsertOperation(string key, object value, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, LockHandle lockHandle, LockAccessType accessType, CacheDataNotificationCallback cacheItemUdpatedCallback, CacheDataNotificationCallback cacheItemRemovedCallaback, EventDataFilter itemUpdateDataFilter, EventDataFilter itemRemovedDataFilter, ref long size, bool allowQueryTags) { _webCache.InsertOperation(key, value, absoluteExpiration, slidingExpiration, priority, lockHandle, accessType, cacheItemUdpatedCallback, cacheItemRemovedCallaback, itemUpdateDataFilter, itemRemovedDataFilter, ref size, true); }
/// <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, EventType eventType) { if (callback == null) { return(null); //FAIL CONDITION } short[] returnValue = new short[] { -1, -1 }; //First value update callback ref & sencond is remove callbackref foreach (EventType type in Enum.GetValues(typeof(EventType))) { if (type == EventType.ItemAdded) //ItemAdded not supported Yet { continue; } lock (SyncLockSelective) { ResourcePool pool = null; ResourcePool poolID = null; #region pool selection if (type == EventType.ItemRemoved && (eventType & EventType.ItemRemoved) != 0) { pool = _selectiveRemoveEventPool; poolID = _selectiveRemoveEventIDPool; } else if (type == EventType.ItemUpdated && (eventType & EventType.ItemUpdated) != 0) { pool = _selectiveUpdateEventPool; poolID = _selectiveUpdateEventIDPool; } if (pool == null) { continue; } #endregion while (true) { int i = type == EventType.ItemUpdated ? 0 : 1; if (pool.GetResource(callback) == null) { returnValue[i] = type == EventType.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; } //add it again into the table for updating ref count. pool.AddResource(callback, cref); poolID.AddResource(cref, callback); returnValue[i] = cref; break; } catch (NullReferenceException) { continue; } } } } } return(returnValue); }
internal virtual CacheEventDescriptor RegisterCacheNotificationInternal(string key, CacheDataNotificationCallback callback, EventType eventType, EventDataFilter datafilter, bool notifyOnItemExpiration) { if (_cacheImpl == null) throw new OperationFailedException("Cache is not initialized"); CacheEventDescriptor discriptor = null; try { if (key != null) { short[] callbackRefs = _eventManager.RegisterSelectiveEvent(callback, eventType, datafilter); _cacheImpl.RegisterKeyNotificationCallback(key, callbackRefs[0], callbackRefs[1], datafilter, notifyOnItemExpiration); } } catch (Exception) { if (ExceptionsEnabled) throw; } return discriptor; }
/// <summary> /// You can use this to notify applications when their objects are updated or removed in the cache. /// Callbacks can be registered against <see cref=" EventType"/> for the key the items is inserted to. /// To register different <see cref="EventDataFilter"/> for different <see cref="EventType"/>, you can call this function mutiple times /// with a different <see cref="EventType"/>. /// Callback are overriden for the same <see cref="EventType"/> if called again. /// <see cref="EventType.ItemAdded"/> is not supported yet. /// </summary> /// <param name="callback">Callback to be raised when an item is updated or removed</param> /// <param name="eventType"><see cref="EventType"/> the callback is registered against</param> /// <param name="datafilter"><see cref="EventDataFilter"/> for every <see cref="EventType"/> registered against</param> public void SetCacheDataNotification(CacheDataNotificationCallback callback, EventType eventType) { EventDataFilter datafilter = EventDataFilter.None; if (callback == null) return; if ((eventType & EventType.ItemRemoved) != 0) { _cacheItemRemovedCallback = callback; _itemRemovedDataFilter = datafilter; } if ((eventType & EventType.ItemUpdated) != 0) { _cacheItemUpdateCallback = callback; _itemUpdatedDataFilter = datafilter; } }
/// <summary> /// Registeres the callback sepeartely and returns short values of registeredCallbacks /// </summary> /// <param name="key"></param> /// <param name="callback"></param> /// <param name="eventType"></param> /// <param name="datafilter"></param> /// <returns>short array,<para>1st element is updated callbackRef</para><para>2st element is removed callbackRef</para></returns> internal short[] RegisterSelectiveEvent(CacheDataNotificationCallback callback, EventType eventType, EventDataFilter datafilter) { if (callback != null) { if (_selectiveUpdateEventPool == null) { _selectiveUpdateEventPool = new ResourcePool(); _selectiveUpdateEventIDPool = new ResourcePool(); } if (_selectiveRemoveEventPool == null) { _selectiveRemoveEventPool = new ResourcePool(); _selectiveRemoveEventIDPool = new ResourcePool(); } return RegisterSelectiveDiscriptor(callback, eventType); } else return null; }
//Creation is CacheDesriptor's responsiblity internal static CacheEventDescriptor CreateCacheDiscriptor(EventType eventType, string cacheName, CacheDataNotificationCallback callback, EventDataFilter datafilter) { CacheEventDescriptor descriptor = new CacheEventDescriptor(); descriptor.RegisteredAgainst = eventType; descriptor.CacheName = cacheName; descriptor.CacheDataNotificationCallback = callback; descriptor.IsRegistered = true; descriptor.DataFilter = datafilter; return descriptor; }
/// <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, EventType eventType) { if (callback == null) return null; //FAIL CONDITION short[] returnValue = new short[] { -1, -1 }; //First value update callback ref & sencond is remove callbackref foreach (EventType type in Enum.GetValues(typeof(EventType))) { if (type == EventType.ItemAdded) //ItemAdded not supported Yet continue; lock (SyncLockSelective) { ResourcePool pool = null; ResourcePool poolID = null; #region pool selection if (type == EventType.ItemRemoved && (eventType & EventType.ItemRemoved) != 0) { pool = _selectiveRemoveEventPool; poolID = _selectiveRemoveEventIDPool; } else if (type == EventType.ItemUpdated && (eventType & EventType.ItemUpdated) != 0) { pool = _selectiveUpdateEventPool; poolID = _selectiveUpdateEventIDPool; } if (pool == null) continue; #endregion while (true) { int i = type == EventType.ItemUpdated ? 0 : 1; if (pool.GetResource(callback) == null) { returnValue[i] = type == EventType.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; } } } } } return returnValue; }
/// <summary> /// You can use this to notify applications when their objects are updated or removed in the cache. /// Callbacks can be registered against <see cref=" EventType"/> for the key the items is inserted to. /// Callback are overriden for the same <see cref="EventType"/> if called again. /// <see cref="EventType.ItemAdded"/> is not supported yet. /// </summary> /// <param name="callback">Callback to be raised when an item is updated or removed</param> /// <param name="eventType"><see cref="EventType"/> the callback is registered against</param> public void SetCacheDataNotification(CacheDataNotificationCallback callback, EventType eventType) { SetCacheDataNotification(callback, eventType, EventDataFilter.None); }