private unsafe void _PollImpl(TrinityMessage poll_req) { m_mod.SendMessage(m_client, poll_req.Buffer, poll_req.Size, out var poll_rsp); var sp = PointerHelper.New(poll_rsp.Buffer + poll_rsp.Offset); //HexDump.Dump(poll_rsp.ToByteArray()); //Console.WriteLine($"poll_rsp.Size = {poll_rsp.Size}"); //Console.WriteLine($"poll_rsp.Offset = {poll_rsp.Offset}"); var payload_len = poll_rsp.Size - TrinityProtocol.TrinityMsgHeader; if (payload_len < sizeof(long) + sizeof(int)) { throw new IOException("Poll response corrupted."); } var errno = *(sp.ip - 1); try { if (errno == 2) { Log.WriteLine(LogLevel.Warning, $"{nameof(TrinityClient)}: server drops our connection. Registering again."); RestartPolling(); return; } if (errno != 0) { return; } var pctx = *sp.lp++; var msg_len = *sp.ip++; if (msg_len < 0) { return; // no events } MessageBuff msg_buff = new MessageBuff { Buffer = sp.bp, Length = (uint)msg_len }; MessageDispatcher(&msg_buff); // !Note, void-response messages are not acknowledged. // Server would not be aware of client side error in this case. // This is by-design and an optimization to reduce void-response // message delivery latency. In streaming use cases this will be // very useful. try { if (pctx != 0) { _PostResponseImpl(pctx, &msg_buff); } } finally { Memory.free(msg_buff.Buffer); } } finally { poll_rsp.Dispose(); } }
public unsafe void SendMessage(byte *message, int size) { byte * header = stackalloc byte[TrinityProtocol.MsgHeader + sizeof(int)]; byte **bufs = stackalloc byte *[2]; int * sizes = stackalloc int[2]; bufs[0] = header; bufs[1] = message; sizes[0] = TrinityProtocol.MsgHeader + sizeof(int); sizes[1] = size; PointerHelper sp = PointerHelper.New(header); *sp.ip = size + sizeof(int) + TrinityProtocol.TrinityMsgHeader; *(sp.bp + TrinityProtocol.MsgTypeOffset) = (byte)TrinityMessageType.SYNC; *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqMessageType.RedirectMessage; *(int *)(sp.bp + TrinityProtocol.MsgHeader) = partitionId; m_mod.SendMessage(m_ep, bufs, sizes, 2); }
public unsafe TrinityErrorCode LoadCell(long cellId, out byte[] cellBuff, out ushort cellType) { using (var req = new __CellIdStructWriter(cellId)) { TrinityResponse rsp = null; TrinityErrorCode errcode = TrinityErrorCode.E_RPC_EXCEPTION; cellBuff = null; cellType = 0; try { var sp = PointerHelper.New(req.buffer); *sp.ip++ = TrinityProtocol.TrinityMsgHeader + sizeof(long); *sp.sp++ = (short)TrinityMessageType.SYNC_WITH_RSP; *sp.sp++ = (short)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.LoadCell; m_mod.SendMessage(m_ep, req.buffer, req.BufferLength, out rsp); sp = PointerHelper.New(rsp.Buffer); errcode = (TrinityErrorCode)(*sp.ip++); if (errcode == TrinityErrorCode.E_SUCCESS) { var length = *sp.ip++; cellType = (ushort)(*sp.sp++); cellBuff = new byte[length]; fixed(byte *p = cellBuff) { Memory.memcpy(p, sp.bp, (ulong)length); } } /* otherwise, fails with returned error code */ } finally { rsp?.Dispose(); } return(errcode); } }