/// <summary> /// /// </summary> /// <param name="trans"></param> /// <param name="dataList"></param> /// <returns></returns> public static void TransUpdateEntity(IRedisTransaction trans, IEnumerable <AbstractEntity> dataList) { var groupList = dataList.GroupBy(t => t.GetType().FullName); foreach (var g in groupList) { string typeName = g.Key; var keys = new List <byte[]>(); var values = new List <byte[]>(); var removeKeys = new List <byte[]>(); var enm = g.GetEnumerator(); while (enm.MoveNext()) { AbstractEntity entity = enm.Current; string keyCode = entity.GetKeyCode(); var keybytes = ToByteKey(keyCode); if (entity.IsDelete) { removeKeys.Add(keybytes); continue; } entity.Reset(); keys.Add(keybytes); values.Add(_serializer.Serialize(entity)); } TransUpdateEntity(trans, typeName, keys.ToArray(), values.ToArray(), removeKeys.ToArray()); } }
/// <summary> /// Try update entity /// </summary> /// <param name="dataList"></param> /// <returns></returns> public static bool TryUpdateEntity(IEnumerable <AbstractEntity> dataList) { var groupList = dataList.GroupBy(t => t.GetType().FullName); foreach (var g in groupList) { string typeName = g.Key; string redisKey = typeName; try { var keys = new List <byte[]>(); var values = new List <byte[]>(); var removeKeys = new List <byte[]>(); var enm = g.GetEnumerator(); while (enm.MoveNext()) { AbstractEntity entity = enm.Current; string keyCode = entity.GetKeyCode(); var keybytes = ToByteKey(keyCode); redisKey += EntityKeySplitChar + keyCode; if (entity.IsDelete) { removeKeys.Add(keybytes); continue; } entity.Reset(); keys.Add(keybytes); values.Add(_serializer.Serialize(entity)); } UpdateEntity(typeName, keys.ToArray(), values.ToArray(), removeKeys.ToArray()); return(true); } catch (Exception ex) { TraceLog.WriteError("Update entity \"{0}\" error:{1}", redisKey, ex); } } return(false); }
private static void OnEntitySyncQueue(object state) { if (Interlocked.CompareExchange(ref _entityQueueRunning, 1, 0) == 0) { try { var tempRemove = Interlocked.Exchange(ref _entityRemoteSet, new HashSet <string>()); var temp = Interlocked.Exchange(ref _entitySet, new HashSet <string>()); if (temp.Count == 0 || _queueWatchTimers == null) { return; } TraceLog.WriteWarn("OnEntitySyncQueue execute count:{0}, success:{1}/total {2}, fail:{3} start...", temp.Count, ExecuteSuccessCount, SendWaitCount, ExecuteFailCount); RedisConnectionPool.Process(client => { while (temp.Count > 0) { var dumpSet = temp.Take(ExecuteCount).ToArray(); var pipeline = client.CreatePipeline(); try { bool hasPost = false; foreach (var key in dumpSet) { var keyValues = key.Split('_', '|'); if (keyValues.Length != 3) { TraceLog.WriteWarn("OnEntitySyncQueue:{0}", key); ExecuteFailCount++; continue; } AbstractEntity entity = CacheFactory.GetPersonalEntity(key) as AbstractEntity; int id = keyValues[1].ToInt(); string keyCode = keyValues[2]; string redisKey = string.Format("{0}_{1}", keyValues[0], keyCode); string hashId = GetRedisSyncQueueKey(id); byte[] idBytes = BufferUtils.GetBytes(id); var keyBytes = RedisConnectionPool.ToByteKey(redisKey); bool isDelete; byte[] entityBytes; if (entity != null) { isDelete = entity.IsDelete; entityBytes = _serializer.Serialize(entity); //modify resean: set unchange status. entity.Reset(); } else if (tempRemove.Contains(key)) { entityBytes = new byte[0]; isDelete = true; } else { ExecuteFailCount++; TraceLog.WriteError("EntitySync queue key {0} faild object is null.", key); continue; } byte[] stateBytes = BufferUtils.GetBytes(isDelete ? 1 : 0); byte[] values = BufferUtils.MergeBytes(BufferUtils.GetBytes(idBytes.Length + stateBytes.Length), idBytes, stateBytes, entityBytes); pipeline.QueueCommand(c => { ((RedisClient)c).HSet(hashId, keyBytes, values); }); hasPost = true; ExecuteSuccessCount++; } if (hasPost) { pipeline.Flush(); } } finally { pipeline.Dispose(); } try { foreach (var key in dumpSet) { temp.Remove(key); } } catch (Exception) { } } }); } catch (Exception ex) { TraceLog.WriteError("EntitySync queue {0}", ex); } finally { Interlocked.Exchange(ref _entityQueueRunning, 0); } } }