ScutGame / Scut

Scut is a free, open source, stable game server framework, which support C#/Python/Lua script, and support Unity3d, Cocos2dx, FlashAir client access.
1.33k stars 577 forks source link

PersonalCacheStruct<GameUser> RemoveCache can not be success #15

Open Jesse1205 opened 8 years ago

Jesse1205 commented 8 years ago

fail: var cache = new PersonalCacheStruct(); var user = cache.FindKey("138021"); //user has value cache.RemoveCache(user); // return true var temp = cache.FindKey("138021"); //return null success: var cache = new PersonalCacheStruct(); var user = cache.FindKey("138021"); //user has value cache.RemoveCache(user); // return true cache.RemoveCache(user); // return false var temp = cache.FindKey("138021"); //temp has value so , RemoveCache() can not work well !

kybird commented 8 years ago

EntityContainer.cs

change below function

        public bool TryRemove(string groupKey, string key, Func<T, bool> callback)
        {

            CacheItemSet itemSet;
            if (Container.TryGetValue(groupKey, out itemSet))
            {
                T entityData;
                var items = (BaseCollection)itemSet.GetItem();
                if (items.TryRemove(key, out entityData))
                {
                    entityData.IsInCache = false;
                    entityData.IsExpired = true;
                    if (callback != null && callback(entityData))
                    {
                        //Not trigger event notify
                        entityData.Dispose();
                    }

                    // BUG
                    //return true;
                }
                if (items.Count == 0 && Container.TryRemove(groupKey, out itemSet))
                {
                    itemSet.ResetStatus();
                    itemSet.Dispose();
                }
            }
            return false;
        }
kybird commented 7 years ago

My solution makes bad effect. Do not apply it.

reproduce step

  1. remark "return true" in TryRemove function in EntityContainer.cs
           var cacheSet = new PersonalCacheStruct<DBSaveTestEntity>();

            var entity = new DBSaveTestEntity()
            {
                UserID = 9999991,
                UserName = "99999991",
            };

            cacheSet.Add(new DBSaveTestEntity() { UserID = 9999991, UserName = "9999991" });
            cacheSet.Add(new DBSaveTestEntity() { UserID = 9999992, UserName = "9999992" });
            cacheSet.Add(new DBSaveTestEntity() { UserID = 9999993, UserName = "9999993" });

            var entity1 = cacheSet.FindKey("9999991");
            var entity2 = cacheSet.FindKey("9999992");
            var entity3 = cacheSet.FindKey("9999993");

            Assert.AreEqual(entity1.UserID , "9999991".ToLong());
            Assert.AreEqual(entity2.UserID , "9999992".ToLong());
            Assert.AreEqual(entity3.UserID ,"9999993".ToLong());

            // reproduce problem
            cacheSet.RemoveCache(entity1);

            var deleted_entity = cacheSet.FindKey("9999991");
            // deleted_entity will have data.
            // because cacheSet think this is first time. it load data from redis