コード例 #1
0
        private void RegisterCacheBackplane(ICacheBackplane <TKey, TValue> backplane)
        {
            // this should have been checked during activation already, just to be totally sure...
            if (_cacheHandles.Any(p => p.Configuration.IsBackplaneSource))
            {
                // added includeSource param to get the handles which need to be synced.
                // in case the backplane source is non-distributed (in-memory), only remotly triggered remove and clear should also
                // trigger a sync locally. For distribtued caches, we expect that the distributed cache is already the source and in sync
                // as that's the layer which triggered the event. In this case, only other in-memory handles above the distribtued, would be synced.
                var handles = new Func <bool, IBaseCacheHandle <TKey, TValue>[]>((includSource) =>
                {
                    var handleList = new List <IBaseCacheHandle <TKey, TValue> >();
                    foreach (var handle in _cacheHandles)
                    {
                        if (!handle.Configuration.IsBackplaneSource ||
                            (includSource && handle.Configuration.IsBackplaneSource && !handle.IsDistributedCache))
                        {
                            handleList.Add(handle);
                        }
                    }
                    return(handleList.ToArray());
                });

                backplane.Changed += (sender, args) =>
                {
                    if (Logger.IsEnabled(LogLevel.Debug))
                    {
                        Logger.LogDebug($"Backplane event: [Changed] for '{args.Key}'.");
                    }

                    EvictFromHandles(args.Key, handles(false));
                    switch (args.Action)
                    {
                    case CacheItemChangedEventAction.Add:
                        TriggerOnAdd(args.Key, CacheActionEventArgOrigin.Remote);
                        break;

                    case CacheItemChangedEventAction.Put:
                        TriggerOnPut(args.Key, CacheActionEventArgOrigin.Remote);
                        break;

                    case CacheItemChangedEventAction.Update:
                        TriggerOnUpdate(args.Key, CacheActionEventArgOrigin.Remote);
                        break;
                    }
                };

                backplane.Removed += (sender, args) =>
                {
                    if (_logTrace)
                    {
                        Logger.LogTrace($"Backplane event: [Remove] of {args.Key}.");
                    }

                    EvictFromHandles(args.Key, handles(true));
                    TriggerOnRemove(args.Key, CacheActionEventArgOrigin.Remote);
                };

                backplane.Cleared += (sender, args) =>
                {
                    if (_logTrace)
                    {
                        Logger.LogTrace("Backplane event: [Clear].");
                    }

                    ClearHandles(handles(true));
                    TriggerOnClear(CacheActionEventArgOrigin.Remote);
                };
            }
        }
コード例 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaseCacheManager{TCacheValue}"/> class
        /// using the specified <paramref name="configuration"/>.
        /// If the name of the <paramref name="configuration"/> is defined, the cache manager will
        /// use it. Otherwise a random string will be generated.
        /// </summary>
        /// <param name="configuration">
        /// The configuration which defines the structure and complexity of the cache manager.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        /// When <paramref name="configuration"/> is null.
        /// </exception>
        /// <see cref="CacheFactory"/>
        /// <see cref="ConfigurationBuilder"/>
        /// <see cref="BaseCacheHandle{TCacheValue}"/>
        public BaseCacheManager(IServiceProvider sp,
                                ILogger <BaseCacheManager <TKey, TValue> > logger,
                                IOptions <CacheManagerConfiguration <TKey, TValue> > configuration,
                                IEnumerable <IBaseCacheHandle <TKey, TValue> > handles)
        {
            CacheManagerConfiguration <TKey, TValue> config = configuration.Value;

            NotNullOrWhiteSpace(config.Name, nameof(config.Name));

            Configuration = configuration.Value;

            //var serializer = CacheReflectionHelper.CreateSerializer(configuration, loggerFactory);

            Logger = logger;

            _logTrace = Logger.IsEnabled(LogLevel.Trace);

            Logger.LogInformation("Cache manager: adding cache handles...");

            try
            {
                _cacheHandles = handles.ToArray();//CacheReflectionHelper.CreateCacheHandles(this, loggerFactory, serializer).ToArray();

                var index = 0;
                foreach (var handle in _cacheHandles)
                {
                    var handleIndex = index;
                    handle.OnCacheSpecificRemove += (sender, args) =>
                    {
                        // added sync for using backplane with in-memory caches on cache specific removal
                        // but commented for now, this is not really needed if all instances use the same expiration etc, would just cause dublicated events
                        ////if (_cacheBackplane != null && handle.Configuration.IsBackplaneSource && !handle.IsDistributedCache)
                        ////{
                        ////    if (string.IsNullOrEmpty(args.Region))
                        ////    {
                        ////        _cacheBackplane.NotifyRemove(args.Key);
                        ////    }
                        ////    else
                        ////    {
                        ////        _cacheBackplane.NotifyRemove(args.Key, args.Region);
                        ////    }
                        ////}

                        // base cache handle does logging for this

                        if (Configuration.UpdateMode == CacheUpdateMode.Up)
                        {
                            if (_logTrace)
                            {
                                Logger.LogTrace($"Cleaning handles above '{handleIndex}' because of remove event.");
                            }

                            EvictFromHandlesAbove(args.Key, handleIndex);
                        }

                        // moving down below cleanup, optherwise the item could still be in memory
                        TriggerOnRemoveByHandle(args.Key, args.Reason, handleIndex + 1, args.Value);
                    };

                    index++;
                }

                _cacheBackplane = sp.GetService <ICacheBackplane <TKey, TValue> >();
                if (_cacheBackplane != null)
                {
                    RegisterCacheBackplane(_cacheBackplane);
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error occurred while creating the cache manager.");
                throw;
            }
        }