Exemple #1
0
        private void OnLoadReply(Msg_DL_LoadResult msg, PBChannel channel, int src, uint session)
        {
            KeyString key = KeyString.Wrap(msg.PrimaryKeys);
            ConcurrentDictionary <KeyString, LoadRequestInfo> dict;

            if (m_LoadRequests.TryGetValue(msg.MsgId, out dict))
            {
                LoadRequestInfo info;
                if (dict.TryGetValue(key, out info))
                {
                    if (info.m_Request.SerialNo == msg.SerialNo)
                    {
                        if (null != info.m_Callback)
                        {
                            info.m_Callback(msg);
                        }
                        LoadRequestInfo delInfo;
                        if (dict.TryRemove(key, out delInfo))
                        {
                            m_LoadRequestPool.Recycle(delInfo);
                        }
                    }
                }
            }
        }
Exemple #2
0
 private void DSLoadHandler(Msg_LD_Load msg, PBChannel channel, int handle, uint seq)
 {
     try {
         DataCacheSystem.Instance.LoadActionQueue.QueueAction <Msg_LD_Load, PBChannel, int>(DataCacheSystem.Instance.Load, msg, channel, handle);
     } catch (Exception e) {
         var errorReply = new Msg_DL_LoadResult();
         errorReply.MsgId = msg.MsgId;
         errorReply.PrimaryKeys.AddRange(msg.PrimaryKeys);
         errorReply.SerialNo  = msg.SerialNo;
         errorReply.ErrorNo   = Msg_DL_LoadResult.ErrorNoEnum.Exception;
         errorReply.ErrorInfo = e.Message;
         channel.Send(errorReply);
         LogSys.Log(LOG_TYPE.ERROR, "Load data failed. MsgId:{0}, Key:{1} Error:{2} Detail:{3}", msg.MsgId, msg.PrimaryKeys, e.Message, e.StackTrace);
     }
 }
    internal static void Load(Msg_LD_Load msg, MyAction <Msg_DL_LoadResult> callback)
    {
        Msg_DL_LoadResult ret = new Msg_DL_LoadResult();

        ret.MsgId = msg.MsgId;
        ret.PrimaryKeys.AddRange(msg.PrimaryKeys);
        ret.SerialNo = msg.SerialNo;;
        ret.ErrorNo  = Msg_DL_LoadResult.ErrorNoEnum.Success;
        if (DataCacheConfig.IsPersistent)
        {
            try {
                for (int i = 0; i < msg.LoadRequests.Count; ++i)
                {
                    Msg_LD_SingleLoadRequest req = msg.LoadRequests[i];
                    switch (req.LoadType)
                    {
                    case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadAll: {
                        int start = req.Start;
                        int count = req.Count;
                        List <GeneralRecordData> datas = DataDML.LoadAll(req.MsgId, start, count);
                        foreach (GeneralRecordData data in datas)
                        {
                            Msg_DL_SingleRowResult result = new Msg_DL_SingleRowResult();
                            result.MsgId = req.MsgId;
                            result.PrimaryKeys.AddRange(data.PrimaryKeys);
                            result.ForeignKeys.AddRange(data.ForeignKeys);
                            result.DataVersion = data.DataVersion;
                            result.Data        = data.Data;
                            ret.Results.Add(result);
                        }
                    }
                    break;

                    case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadSingle: {
                        GeneralRecordData      data   = DataDML.LoadSingle(req.MsgId, req.Keys);
                        Msg_DL_SingleRowResult result = new Msg_DL_SingleRowResult();
                        result.MsgId = req.MsgId;

                        if (data != null)
                        {
                            result.PrimaryKeys.AddRange(data.PrimaryKeys);
                            result.ForeignKeys.AddRange(data.ForeignKeys);
                            result.DataVersion = data.DataVersion;
                            result.Data        = data.Data;
                        }
                        else
                        {
                            result.PrimaryKeys.AddRange(msg.PrimaryKeys);
                            result.ForeignKeys.Clear();
                            result.DataVersion = -1;
                            result.Data        = null;
                            ret.ErrorNo        = Msg_DL_LoadResult.ErrorNoEnum.NotFound;
                        }
                        ret.Results.Add(result);
                    }
                    break;

                    case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadMulti: {
                        List <GeneralRecordData> dataList = DataDML.LoadMulti(req.MsgId, req.Keys);
                        foreach (GeneralRecordData data in dataList)
                        {
                            Msg_DL_SingleRowResult result = new Msg_DL_SingleRowResult();
                            result.MsgId = req.MsgId;
                            result.PrimaryKeys.AddRange(data.PrimaryKeys);
                            result.ForeignKeys.AddRange(data.ForeignKeys);
                            result.DataVersion = data.DataVersion;
                            result.Data        = data.Data;
                            ret.Results.Add(result);
                        }
                    }
                    break;
                    }
                }
            } catch (Exception ex) {
                ret.ErrorNo   = Msg_DL_LoadResult.ErrorNoEnum.PostError;
                ret.ErrorInfo = ex.Message;
                LogSys.Log(LOG_TYPE.ERROR, ConsoleColor.Red, "Load data from mysql ERROR. MsgId:{0}, Key:{1}\nErrorMessage:{2}\nStackTrace:{3}",
                           msg.MsgId, msg.PrimaryKeys, ex.Message, ex.StackTrace);
            } finally {
                DataCacheSystem.Instance.QueueAction(callback, ret);
            }
        }
        else
        {
            ret.ErrorNo   = Msg_DL_LoadResult.ErrorNoEnum.NotFound;
            ret.ErrorInfo = string.Empty;
            DataCacheSystem.Instance.QueueAction(callback, ret);
        }
    }
Exemple #4
0
        private void OnTick()
        {
            long curTime = TimeUtility.GetLocalMilliseconds();

            if (m_LastTickTime != 0)
            {
                long elapsedTickTime = curTime - m_LastTickTime;
                if (elapsedTickTime > c_WarningTickTime)
                {
                    LogSys.Log(LOG_TYPE.MONITOR, "DataCacheThread Tick:{0}", elapsedTickTime);
                }
            }
            m_LastTickTime = curTime;

            if (m_LastLogTime + 60000 < curTime)
            {
                m_LastLogTime = curTime;
                DebugPoolCount((string msg) => {
                    LogSys.Log(LOG_TYPE.INFO, "DataCacheThread.DispatchActionQueue {0}", msg);
                });
                DebugActionCount((string msg) => {
                    LogSys.Log(LOG_TYPE.MONITOR, "DataCacheThread.DispatchActionQueue {0}", msg);
                });
                LogSys.Log(LOG_TYPE.MONITOR, "DataCacheThread.ThreadActionQueue Current Action {0}", m_Thread.CurActionNum);
                LogSys.Log(LOG_TYPE.MONITOR, "DataCacheThread Load Request Count {0} Save Request Count {1}", CalcLoadRequestCount(), CalcSaveRequestCount());
            }
            if (UserServerConfig.DataStoreAvailable == true)
            {
                if (m_LastOperateTickTime + c_OperateTickInterval < curTime)
                {
                    m_LastOperateTickTime = curTime;
                    //Load操作
                    foreach (var pair in m_LoadRequests)
                    {
                        int msgId = pair.Key;
                        ConcurrentDictionary <KeyString, LoadRequestInfo> dict = pair.Value;
                        foreach (var reqPair in dict)
                        {
                            KeyString       primaryKey = reqPair.Key;
                            LoadRequestInfo req        = reqPair.Value;
                            if (req.m_LastSendTime + UserServerConfig.DSRequestTimeout < curTime)
                            {
                                m_WaitDeletedLoadRequests.Add(primaryKey, req.m_Request.SerialNo);
                                Msg_DL_LoadResult result = new Msg_DL_LoadResult();
                                result.MsgId = msgId;
                                result.PrimaryKeys.AddRange(primaryKey.Keys);
                                result.SerialNo  = req.m_Request.SerialNo;
                                result.ErrorNo   = Msg_DL_LoadResult.ErrorNoEnum.TimeoutError;
                                result.ErrorInfo = "Timeout Error";
                                if (null != req.m_Callback)
                                {
                                    DispatchAction(req.m_Callback, result);
                                }
                            }
                        }
                        foreach (var delPair in m_WaitDeletedLoadRequests)
                        {
                            LoadRequestInfo info;
                            if (dict.TryRemove(delPair.Key, out info))
                            {
                                if (info.m_Request.SerialNo == delPair.Value)
                                {
                                    m_LoadRequestPool.Recycle(info);
                                }
                                else
                                {
                                    dict.TryAdd(delPair.Key, info);
                                }
                            }
                        }
                        m_WaitDeletedLoadRequests.Clear();
                    }
                    //Save操作
                    foreach (var pair in m_SaveRequestQueues)
                    {
                        int msgId = pair.Key;
                        ConcurrentDictionary <KeyString, ConcurrentQueue <SaveRequestInfo> > dict = pair.Value;
                        foreach (var reqPair in dict)
                        {
                            KeyString primaryKey = reqPair.Key;
                            ConcurrentQueue <SaveRequestInfo> saveReqQueue = reqPair.Value;
                            SaveRequestInfo req;
                            if (saveReqQueue.TryPeek(out req))
                            {
                                if (req.m_LastSendTime + UserServerConfig.DSRequestTimeout < curTime)
                                {
                                    //超时,重新发送
                                    LogSys.Log(LOG_TYPE.ERROR, "DataCacheThread. SaveRequest timeout. MsgId:{0}, PrimaryKey:{1}, SerialNo:{2}",
                                               msgId, KeyString.Wrap(req.m_Request.PrimaryKeys), req.m_Request.SerialNo);
                                    m_DataStoreChannel.Send(req.m_Request);
                                    req.m_LastSendTime = curTime;
                                }
                            }
                            if (dict.Count > c_MaxRecordPerMessage && saveReqQueue.Count == 0)
                            {
                                m_WaitDeleteSaveRequests.Add(primaryKey);
                            }
                        }
                        foreach (KeyString key in m_WaitDeleteSaveRequests)
                        {
                            lock (m_SaveRequestQueuesLock) {
                                ConcurrentQueue <SaveRequestInfo> queue;
                                if (dict.TryGetValue(key, out queue))
                                {
                                    if (queue.Count == 0)
                                    {
                                        ConcurrentQueue <SaveRequestInfo> dummy;
                                        dict.TryRemove(key, out dummy);
                                    }
                                }
                            }
                        }
                        m_WaitDeleteSaveRequests.Clear();
                    }
                }
                if (m_LastDSConnectTime + c_DSConnectInterval < curTime)
                {
                    m_LastDSConnectTime = curTime;
                    if (m_CurrentStatus != ConnectStatus.Connected)
                    {
                        ConnectDataStore();
                    }
                }
            }
        }
Exemple #5
0
    //==========================通过QueueAction调用的方法===========================================
    //注意!回调函数目前在缓存线程与db线程都可能调用,回调函数的实现需要是线程安全的(目前一般都是发消息,满足此条件)。
    internal void Load(Msg_LD_Load msg, PBChannel channel, int handle)
    {
        //首先在缓存中查找数据,若未找到,则到DB中查找
        bool isLoadCache      = true;
        Msg_DL_LoadResult ret = new Msg_DL_LoadResult();

        ret.MsgId = msg.MsgId;
        ret.PrimaryKeys.AddRange(msg.PrimaryKeys);
        ret.SerialNo = msg.SerialNo;
        ret.ErrorNo  = 0;
        for (int i = 0; i < msg.LoadRequests.Count; ++i)
        {
            Msg_LD_SingleLoadRequest req = msg.LoadRequests[i];
            KeyString loadKey            = KeyString.Wrap(req.Keys);
            switch (req.LoadType)
            {
            case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadAll: {
                isLoadCache = false;
            }
            break;

            case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadSingle: {
                InnerCacheItem item = m_InnerCacheSystem.Find(req.MsgId, loadKey);
                if (item != null)
                {
                    Msg_DL_SingleRowResult result = new Msg_DL_SingleRowResult();
                    result.MsgId = req.MsgId;
                    result.PrimaryKeys.AddRange(req.Keys);
                    result.DataVersion = 0;                 //TODO: 这个DataVersion有用吗?
                    result.Data        = item.DataMessage;
                    ret.Results.Add(result);
                }
                else
                {
                    isLoadCache = false;
                }
            }
            break;

            case Msg_LD_SingleLoadRequest.LoadTypeEnum.LoadMulti: {
                List <InnerCacheItem> itemList = m_InnerCacheSystem.FindByForeignKey(req.MsgId, loadKey);
                foreach (var item in itemList)
                {
                    Msg_DL_SingleRowResult result = new Msg_DL_SingleRowResult();
                    result.MsgId = req.MsgId;
                    result.PrimaryKeys.AddRange(req.Keys);
                    result.DataVersion = 0;                 //TODO: 这个DataVersion有用吗?
                    result.Data        = item.DataMessage;
                    ret.Results.Add(result);
                }
            }
            break;
            }
        }
        if (isLoadCache)
        {
            channel.Send(ret);
            LogSys.Log(LOG_TYPE.INFO, "Load data from cache. MsgId:{0}, Key:{1}", msg.MsgId, KeyString.Wrap(msg.PrimaryKeys).ToString());
        }
        else
        {
            //查找DB交给DBLoad线程操作
            DbThreadManager.Instance.LoadActionQueue.QueueAction(DataLoadImplement.Load, msg, (MyAction <Msg_DL_LoadResult>)((Msg_DL_LoadResult result) => {
                if (result.ErrorNo == Msg_DL_LoadResult.ErrorNoEnum.Success)
                {
                    foreach (Msg_DL_SingleRowResult row in result.Results)
                    {
                        m_InnerCacheSystem.AddOrUpdate(row.MsgId, KeyString.Wrap(row.PrimaryKeys), KeyString.Wrap(row.ForeignKeys), row.Data);
                    }
                }
                channel.Send(result);
                LogSys.Log(LOG_TYPE.INFO, "Load data from database. MsgId:{0}, Key:{1}", msg.MsgId, KeyString.Wrap(msg.PrimaryKeys).ToString());
            }));
        }
    }