Scut:缓存管理

  Scut 的缓存管理看起来还是蛮复杂的。

    redis 本身就有内存缓存+持久化的作用,Scut还是自己封装了一层内存缓存+Redis缓存+持久化。

 

这是一个缩略版本的结构图。

1. 上半部分是通用的缓存池结构,用来存放各类缓存数据。

  第一层Dictionary是按大类区分:Entity_{0}、Personal_(0),type.name 等;

    第二层Dictionary则是进一步细分,比如同样一个type下的 type.name +"UserID";

2. 下半部分则是应用层对缓存的操作器,包含数据取用+操作方法,应用层数据结构要按照一定的规则进行封装,才能直接使用Scut提供的“带数据修改事件”的各类组件。

 

CacheItemSet 的作用:

Cache 们都会用 CacheItemSet 容器 来装载具体的数据;

        private readonly CacheType _cacheItemType;  //标记了缓存的类型,不同类型的缓存在从redis加载时key的组装方式,释放缓存的规则都不相同
        private readonly bool _isReadOnly;
        private CachePeriod _period;          //缓存的核心:生命周期       
        private IDataExpired _itemData;              //具体的数据
     public bool HasChanged { get; private set; }

生命周期如何起作用?HasChanged 如何起作用?

在 CachePool 里的 DisposeCache 接口有统一处理,但没有发现哪里在定期有效调用?

 

ShareCacheStruct:

        public IEnumerable<T> Take()
        {
            return DataContainer.ToEntityEnumerable(false);
        }
        public IEnumerable<T> ToEntityEnumerable(bool isLoad = false)
        {
            if (isLoad) CheckLoad();
            return Container.GetEnumerable().Select(pari => pari.Value).OfType<CacheItemSet>().Select(itemSet => (T)itemSet.GetItem());
        }

可以知道 ShareCache 从缓存加载数据时,是整块相应类型的数据全部加载出来,适合用来管理配置、处理公有数据。

 

PersonalCache:

        public IEnumerable<T> Take()
        {
            return DataContainer.ToGroupEnumerable();
        }

        public T Take(params object[] keys)
        {
            string key = AbstractEntity.CreateKeyCode(keys);
            return DataContainer.TakeEntityFromKey(key);
        }

它可以单个或整体进行缓存加载,更适合处理单用户的某类型数据。

ShareEntity 比 BaseEntity 多了一个 API:GetIdentityId() 未来有什么作用再观察。

 

AbstractEntity:

        /// <summary>
        /// 存储改变的属性集合
        /// </summary>
        private ConcurrentQueue<string> _changePropertys = new ConcurrentQueue<string>();
        /// <summary>
        /// 等待更新属性
        /// </summary>
        private readonly HashSet<string> _waitUpdateList = new HashSet<string>();

这两个属性,表示 abstracEntity 最重要的作用应该是“部分更新修改过的数据”

持续追踪,发现其作用是向数据库写入修改过的数据:

SqlDataSender.cs:

        public bool Send<T>(params T[] dataList) where T : AbstractEntity
        {
            return Send(dataList, GetPropertyValue, GetPostColumns);
        }

 

那什么时候进行写入修改数据? AbstractEntity 下的 EntityChangeEvent : IItemChangeEvent 是如何起作用的?

IItemChangeEvent:

        [JsonIgnore]
        public bool IsExpired { get; set; }

        [JsonIgnore]
        public bool IsInCache { get; set; }

        /// <summary>
        /// 是否有变更
        /// </summary>
        public abstract bool HasChanged { get; }

        /// <summary>
        /// 绑定实体类的属性名(表的列名)
        /// </summary>
        internal abstract string PropertyName { get; set; }

        /// <summary>
        /// 当前对象变更事件对象
        /// </summary>
        public abstract CacheItemChangeEvent ItemEvent { get; } /// <summary> /// 当前对象的子类变更事件对象 /// </summary> public abstract CacheItemChangeEvent ChildrenEvent { get; }

 

在 AbstractEntity 中,对本身数值进行“修改、删除进行封装的API”,都会调用事件通知 Notify。

AbstractEntity 重载的 Notify API:

        protected override void Notify(object sender, CacheItemEventArgs eventArgs)
        {
            if (_isReadOnly || CheckChnage()) return;
            _hasChanged = true;
            AddChangePropertys(eventArgs.PropertyName);
            PutToChangeKeys(this);
        }
        private void PutToChangeKeys(AbstractEntity entity)
        {
            if (!IsModifying)
            {
                //Auto trigger modify event
                ProfileManager.ChangeEntityByAutoOfMessageQueueTimes(entity.GetType().FullName, entity.GetKeyCode());
                DataSyncQueueManager.Send(entity);
            }
        }

可以看出这个位置并没有真正使用  EntityChangeEvent 机制,而是重写了 Notity(),在修改数据后,直接向底层队列压入修改队列。

转载于:https://www.cnblogs.com/Daniel-Liang/p/5793640.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值