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(); }
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(); }
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(); }
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(); } }
public static unsafe string GetDebugInfo(MessageChunk *msg, bool withData) { var sb = new System.Text.StringBuilder(); GetDebugInfo(sb, msg, withData); return(sb.ToString()); }
internal unsafe void ReturnMessageChunk(MessageChunk *chunk) { Debug.Assert(chunk != null); Node *node = chunk->Node; chunk->Node = null; ReturnNode(node); }
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); }
private unsafe void ProcessRollbackTran(IMessageChannel channel, MessageChunk *first) { var req = new RollbackTranRequire(); req.FastReadFrom(first); channel.ReturnMessageChunks(first); NativeApi.RollbackTransaction(req.TxnPtr, req.IsAbort); }
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(); }
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; }
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); }
internal unsafe void FastReadFrom(MessageChunk *first) { byte *dataPtr = MessageChunk.GetDataPtr(first); ReadCommitted = dataPtr[1] > 0; long *src = (long *)(dataPtr + 2); WaitHandle = new IntPtr(*src); }
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); }
/// <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); }
public void StopReceive() { //使用发送特定消息的方式通知接收Loop停止 unsafe { MessageChunk *chunk = _receiveQueue.GetMessageChunkForWrite(); chunk->Type = 255; chunk->DataLength = 0; _receiveQueue.PostMessageChunk(chunk); } }
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:考虑是否实现计算总数据大小 }
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; } }
public unsafe void ReturnMessageChunks(MessageChunk *first) { MessageChunk *cur = first; MessageChunk *next = null; while (cur != null) { next = cur->Next; _receiveQueue.ReturnMessageChunk(cur); cur = next; } }
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---------------"); } }
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()); }
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("无法加入线程池"); } }
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); }
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; }
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; } } }
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; } }
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); }
/// <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); }
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; } }
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); } }
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)); } } }