コード例 #1
0
        private unsafe void ProcessKVAddRef(IMessageChannel channel, MessageChunk *first)
        {
            var req = channel.Deserialize <KVAddRefRequire>(first);

            NativeApi.ExecKVAddRef(req.TxnPtr, req.WaitHandle, channel.RemoteRuntimeId, new IntPtr(&req));
            req.FreeData();
        }
コード例 #2
0
        private unsafe void ProcessReadIndexByGet(IMessageChannel channel, MessageChunk *first)
        {
            var req = channel.Deserialize <KVGetRequire>(first);

            NativeApi.ReadIndexByGet(req.WaitHandle, channel.RemoteRuntimeId, req.RaftGroupId, req.KeyPtr, req.KeySize, req.DataCF);
            req.FreeData();
        }
コード例 #3
0
        private unsafe void ProcessReadIndexByScan(IMessageChannel channel, MessageChunk *first)
        {
            var req = channel.Deserialize <KVScanRequire>(first);

            NativeApi.ReadIndexByScan(req.WaitHandle, channel.RemoteRuntimeId, new IntPtr(&req));
            req.FreeKeysData();
        }
コード例 #4
0
        private unsafe void ProcessInvokeResponse(IMessageChannel channel, MessageChunk *first)
        {
            var response = channel.Deserialize <InvokeResponse>(first); //TODO:处理反序列化异常

            if (response.Source == InvokeSource.Client || response.Source == InvokeSource.Host)
            {
                GCHandle tcsHandle = GCHandle.FromIntPtr(response.WaitHandle);
                var      tcs       = (PooledTaskSource <AnyValue>)tcsHandle.Target;
                if (response.Error != InvokeResponseError.None) //仅Host,重新包装为异常
                {
                    tcs.SetResultOnOtherThread(AnyValue.From(new Exception((string)response.Result.ObjectValue)));
                }
                else
                {
                    tcs.SetResultOnOtherThread(response.Result);
                }
            }
            else if (response.Source == InvokeSource.Debugger)
            {
                _debugSessionManager.GotInvokeResponse(channel.RemoteRuntimeId, response); //注意暂直接在当前线程处理
            }
            else
            {
                throw new NotImplementedException();
            }
        }
コード例 #5
0
        public static unsafe string GetDebugInfo(MessageChunk *msg, bool withData)
        {
            var sb = new System.Text.StringBuilder();

            GetDebugInfo(sb, msg, withData);
            return(sb.ToString());
        }
コード例 #6
0
        internal unsafe void ReturnMessageChunk(MessageChunk *chunk)
        {
            Debug.Assert(chunk != null);
            Node *node = chunk->Node;

            chunk->Node = null;
            ReturnNode(node);
        }
コード例 #7
0
        private unsafe void ProcessCommitTran(IMessageChannel channel, MessageChunk *first)
        {
            var req = new CommitTranRequire();

            req.FastReadFrom(first);
            channel.ReturnMessageChunks(first);
            NativeApi.CommitTransaction(req.TxnPtr, req.WaitHandle, channel.RemoteRuntimeId);
        }
コード例 #8
0
        private unsafe void ProcessRollbackTran(IMessageChannel channel, MessageChunk *first)
        {
            var req = new RollbackTranRequire();

            req.FastReadFrom(first);
            channel.ReturnMessageChunks(first);
            NativeApi.RollbackTransaction(req.TxnPtr, req.IsAbort);
        }
コード例 #9
0
        private unsafe void ProcessGenPartition(IMessageChannel channel, MessageChunk *first)
        {
            var req  = channel.Deserialize <GenPartitionRequire>(first);
            var info = req.PartitionInfo;

            NativeApi.MetaGenPartition(req.TxnPtr, req.WaitHandle, channel.RemoteRuntimeId, new IntPtr(&info));
            req.FreeData();
        }
コード例 #10
0
        internal unsafe void FastReadFrom(MessageChunk *first)
        {
            byte *dataPtr = MessageChunk.GetDataPtr(first) + 1; //offset 1 byte type
            long *src     = (long *)(dataPtr);

            TxnPtr  = new IntPtr(*src);
            IsAbort = dataPtr[8] != 0;
        }
コード例 #11
0
        internal unsafe void PostMessageChunk(MessageChunk *chunk)
        {
            Node *node = chunk->Node;

            node->AmountWritten = MessageChunk.PayloadHeadSize + chunk->DataLength;
            chunk->Node         = null;
            //Log.Debug($"发送->{MessageChunk.GetDebugInfo(chunk, false)} Written={chunk->Node->AmountWritten}");
            PostNode(node);
        }
コード例 #12
0
        internal unsafe void FastReadFrom(MessageChunk *first)
        {
            byte *dataPtr = MessageChunk.GetDataPtr(first);

            ReadCommitted = dataPtr[1] > 0;
            long *src = (long *)(dataPtr + 2);

            WaitHandle = new IntPtr(*src);
        }
コード例 #13
0
        internal unsafe void FastReadFrom(MessageChunk *first)
        {
            byte *dataPtr = MessageChunk.GetDataPtr(first);
            long *src     = (long *)(dataPtr + 1);

            TxnPtr     = new IntPtr(*src);
            src        = (long *)(dataPtr + 9);
            WaitHandle = new IntPtr(*src);
        }
コード例 #14
0
        /// <summary>
        /// Get MessageChunk for write.
        /// </summary>
        internal unsafe MessageChunk *GetMessageChunkForWrite()
        {
            Node *node = GetNodeForWriting(-1); //暂阻塞调用

            Debug.Assert(node != null);

            MessageChunk *chunk = (MessageChunk *)(BufferStartPtr + node->Offset);

            chunk->Node = node;
            return(chunk);
        }
コード例 #15
0
 public void StopReceive()
 {
     //使用发送特定消息的方式通知接收Loop停止
     unsafe
     {
         MessageChunk *chunk = _receiveQueue.GetMessageChunkForWrite();
         chunk->Type       = 255;
         chunk->DataLength = 0;
         _receiveQueue.PostMessageChunk(chunk);
     }
 }
コード例 #16
0
        public unsafe void Reset(MessageChunk *first)
        {
            //注意:不能加此判断,否则跨进程路由的消息报错
            //if (first->First != first)
            //    throw new ArgumentException(nameof(first));

            _curChunk   = first;
            _curDataPtr = MessageChunk.GetDataPtr(_curChunk);
            _maxDataPtr = _curDataPtr + _curChunk->DataLength;

            //todo:考虑是否实现计算总数据大小
        }
コード例 #17
0
        public unsafe static void PushAll(MessageChunk *head)
        {
            MessageChunk *cur  = head;
            MessageChunk *next = null;

            while (cur != null)
            {
                next = cur->Next;
                Push(new IntPtr(cur)); //pool.Push(new IntPtr(cur));
                cur = next;
            }
        }
コード例 #18
0
        public unsafe void ReturnMessageChunks(MessageChunk *first)
        {
            MessageChunk *cur  = first;
            MessageChunk *next = null;

            while (cur != null)
            {
                next = cur->Next;
                _receiveQueue.ReturnMessageChunk(cur);
                cur = next;
            }
        }
コード例 #19
0
 private static unsafe void GetDebugInfo(System.Text.StringBuilder sb, MessageChunk *msg, bool withData)
 {
     sb.AppendFormat("TYP={0} ID={1} FLAG={2} LEN={3} CUR={6} FST={4} NXT={5}"
                     , (MessageType)msg->Type, msg->ID, msg->Flag, msg->DataLength
                     , new IntPtr(msg->First), new IntPtr(msg->Next), new IntPtr(msg));
     if (withData)
     {
         sb.AppendLine();
         sb.AppendLine("------------DataStart-------------");
         sb.AppendLine(StringHelper.ToHexString(new IntPtr(GetDataPtr(msg)), msg->DataLength));
         sb.AppendLine("------------DataEnd---------------");
     }
 }
コード例 #20
0
        public static unsafe string GetAllDebugInfo(MessageChunk *first, bool withData)
        {
            var sb  = new System.Text.StringBuilder();
            var cur = first;

            while (cur != null)
            {
                GetDebugInfo(sb, cur, withData);
                sb.AppendLine();
                cur = cur->Next;
            }
            return(sb.ToString());
        }
コード例 #21
0
        private unsafe void ProcessStoreCB(IMessageChannel channel, MessageChunk *first)
        {
            var msg = channel.Deserialize <NativeMessage>(first);
            //Log.Debug($"收到存储回调信息: Type={(StoreCBType)msg.Shard} WaitHandle={msg.Handle}");
            GCHandle tsHandle = GCHandle.FromIntPtr(msg.Handle);
            //注意:必须启用线程池,否则ValueTask.Continue时如果存在异步转同步调用(ValueTask.Result)会阻塞消息循环
            var  ts = (PooledTaskSource <NativeMessage>)tsHandle.Target;
            bool ok = ts.SetResultOnOtherThread(msg);

            if (!ok)
            {
                Log.Warn("无法加入线程池");
            }
        }
コード例 #22
0
        internal unsafe MessageChunk *GetMessageChunkForRead()
        {
            Node *node = GetNodeForReading(-1); //暂阻塞调用

            if (node == null)
            {
                return(null);
            }

            MessageChunk *chunk = (MessageChunk *)(BufferStartPtr + node->Offset);

            chunk->Node = node;
            //Log.Debug($"读到数据块<-{MessageChunk.GetDebugInfo(chunk, false)}");
            return(chunk);
        }
コード例 #23
0
        public unsafe void Reset(MessageType msgType, int msgID, ulong sourceId, MessageFlag msgFlag, SharedMessageQueue queue = null)
        {
            _curChunk = null; //必须设置,否则缓存重用有问题

            _msgType  = msgType;
            _msgID    = msgID;
            _sourceId = sourceId;
            _msgFlag  = msgFlag;
            _queue    = queue;

            CreateChunk();

            //第一包设MessageSource
            //_curChunk->MessageSource = srcType;
        }
コード例 #24
0
 public static unsafe void DumpAllData(MessageChunk *first, string file)
 {
     using (var fs = System.IO.File.OpenWrite(file))
     {
         var cur = first;
         while (cur != null)
         {
             byte *dataPtr = GetDataPtr(cur);
             for (int i = 0; i < cur->DataLength; i++)
             {
                 fs.WriteByte(dataPtr[i]);
             }
             cur = cur->Next;
         }
     }
 }
コード例 #25
0
        public unsafe void ProcessMessage(IMessageChannel channel, MessageChunk *first)
        {
            switch ((MessageType)first->Type)
            {
            case MessageType.InvokeResponse:
                ProcessInvokeResponse(channel, first); break;

            case MessageType.MetricRequire:
                ProcessMetricRequire(channel, first); break;

#if FUTURE
            case MessageType.KVGetRequire:
                ProcessReadIndexByGet(channel, first); break;

            case MessageType.KVScanRequire:
                ProcessReadIndexByScan(channel, first); break;

            case MessageType.BeginTranRequire:
                ProcessBeginTran(channel, first); break;

            case MessageType.CommitTranRequire:
                ProcessCommitTran(channel, first); break;

            case MessageType.RollbackTranRequire:
                ProcessRollbackTran(channel, first); break;

            case MessageType.GenPartitionRequire:
                ProcessGenPartition(channel, first); break;

            case MessageType.KVInsertRequire:
                ProcessKVInsert(channel, first); break;

            case MessageType.KVUpdateRequire:
                ProcessKVUpdate(channel, first); break;

            case MessageType.KVDeleteRequire:
                ProcessKVDelete(channel, first); break;

            case MessageType.KVAddRefRequire:
                ProcessKVAddRef(channel, first); break;
#endif
            default:
                channel.ReturnMessageChunks(first);
                Log.Warn($"Unknow MessageType: {first->Type}");
                break;
            }
        }
コード例 #26
0
        private unsafe bool CheckNeedMove()
        {
            if (_curDataPtr == _maxDataPtr)
            {
                if (_curChunk->Next == null)
                {
                    //_curChunk->DumpAllTcpInfo(true);
                    return(false);
                }

                //移至下一消息段
                _curChunk   = _curChunk->Next;
                _curDataPtr = MessageChunk.GetDataPtr(_curChunk);
                _maxDataPtr = _curDataPtr + _curChunk->DataLength;
            }
            return(true);
        }
コード例 #27
0
        /// <summary>
        /// 反序列化消息 注意:不管是否成功归还缓存块至通道
        /// </summary>
        /// <exception>只抛出MessageSerializationException</exception>
        public unsafe T Deserialize <T>(MessageChunk *first) where T : struct, IMessage
        {
            if (first == null)
            {
                throw new MessageSerializationException(MessageSerilizationErrorCode.DeserializeFailByFirstSegmentIsNull, null);
            }
            //??注意:不能判断first->First == first, 因为AppContainer子进程内收到的路由消息已修改第一包

            var mrs = MessageReadStream.ThreadInstance;

            mrs.Reset(first);
            BinSerializer bs = BinSerializer.ThreadInstance;

            bs.Init(mrs);
            T res = default;

            try
            {
                var payloadType = bs.ReadByte(); //不用res = bs.Deserialize();避免box
                if (payloadType != (byte)res.PayloadType)
                {
                    throw new MessageSerializationException(MessageSerilizationErrorCode.DeserializeFailByMessageType, null);
                }

                res.ReadObject(bs);
                mrs.Close();
            }
            catch (MessageSerializationException)
            {
                throw;
            }
            catch (Exception ex) //TODO:单独捕获解密错误信息
            {
                //Log.Warn(ex.StackTrace);
                throw new MessageSerializationException(MessageSerilizationErrorCode.DeserializeFail, ex);
            }
            finally
            {
                ReturnMessageChunks(first);
                bs.Clear();
            }

            return(res);
        }
コード例 #28
0
        public unsafe void ProcessMessage(IMessageChannel channel, MessageChunk *first)
        {
            switch ((MessageType)first->Type)
            {
            case MessageType.InvalidModelsCache:
                ProcessInvalidModelsCache(channel, first); break;

            case MessageType.InvokeRequire:
                ProcessInvokeRequire(channel, new IntPtr(first)); break;

#if FUTURE
            case MessageType.NativeMessage:
                ProcessStoreCB(channel, first); break;
#endif
            default:
                channel.ReturnMessageChunks(first);
                Log.Warn($"Unknow MessageType: {first->Type}");
                break;
            }
        }
コード例 #29
0
        private unsafe void CreateChunk()
        {
            var preChunk = _curChunk;

            if (_queue == null)
            {
                _curChunk = (MessageChunk *)ByteBuffer.Pop();
            }
            else
            {
                _curChunk = _queue.GetMessageChunkForWrite();
            }

            //初始化包的消息头
            _curChunk->Type            = (byte)_msgType;
            _curChunk->ID              = _msgID;
            _curChunk->Flag            = (byte)_msgFlag;
            _curChunk->MessageSourceID = _sourceId;
            _curChunk->DataLength      = MessageChunk.PayloadDataSize;
            //需要设置消息链表
            _curChunk->Next = null;
            if (preChunk == null)
            {
                _curChunk->First = _curChunk;
                _curChunk->Flag |= (byte)MessageFlag.FirstChunk;
            }
            else
            {
                preChunk->Next   = _curChunk;
                _curChunk->First = preChunk->First;
            }
            //设置数据部分位置
            _curDataPtr = MessageChunk.GetDataPtr(_curChunk);
            _maxDataPtr = _curDataPtr + MessageChunk.PayloadDataSize;

            //直接发送preChunk
            if (_queue != null && preChunk != null)
            {
                _queue.PostMessageChunk(preChunk);
            }
        }
コード例 #30
0
        private unsafe void OnMessageChunk(MessageChunk *chunk)
        {
            //Log.Debug($"[{System.Diagnostics.Process.GetCurrentProcess().ProcessName}]收到:{(MessageType)chunk->Type}");
            var  msgId = chunk->ID;
            bool isEnd = (chunk->Flag & (byte)MessageFlag.LastChunk) == (byte)MessageFlag.LastChunk;

            MessageChunk *curChunk = chunk;

            curChunk->Next = null;

            if (_pendingMsgs.TryGetValue(msgId, out IntPtr preChunkPtr))
            {
                MessageChunk *preChunk = (MessageChunk *)preChunkPtr;
                curChunk->First = preChunk->First;
                preChunk->Next  = curChunk;
                if (isEnd)                           //收到完整消息,交给消息处理器处理
                {
                    _pendingMsgs.Remove(msgId);      //先从挂起的消息字典表中移除
                    ProcessMessage(curChunk->First); //再处理完整的消息
                }
                else
                {
                    _pendingMsgs[msgId] = new IntPtr(curChunk); //重置消息ID的最后一包
                }
            }
            else
            {
                curChunk->First = curChunk;
                if (isEnd)                    //就一包
                {
                    ProcessMessage(curChunk); //直接交给消息处理器
                }
                else
                {
                    _pendingMsgs.Add(msgId, new IntPtr(curChunk));
                }
            }
        }