예제 #1
0
        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, BytesReceived = (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();
            }
        }
예제 #2
0
 public PersistedCellEnumerator(byte[] content, long target_lowKey, long target_highKey)
 {
     m_content        = content;
     m_length         = content.Length;
     m_target_lowKey  = target_lowKey;
     m_target_highKey = target_highKey;
     m_handle         = GCHandle.Alloc(content, GCHandleType.Pinned);
     m_bp             = (byte *)m_handle.AddrOfPinnedObject().ToPointer();
     m_sp             = PointerHelper.New(m_bp);
     m_ep             = m_bp + m_length;
 }
예제 #3
0
        private unsafe TrinityMessage _AllocPollMsg(int myInstanceId, int myCookie)
        {
            int           msglen = sizeof(int) + sizeof(int) + TrinityProtocol.MsgHeader;
            byte *        buf    = (byte *)Memory.malloc((ulong)msglen);
            PointerHelper sp     = PointerHelper.New(buf);

            *sp.ip = msglen - TrinityProtocol.SocketMsgHeader;
            *(TrinityMessageType *)(sp.bp + TrinityProtocol.MsgTypeOffset) = TrinityMessageType.SYNC_WITH_RSP;
            *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.PollEvents;
            sp.bp += TrinityProtocol.MsgHeader;
            *sp.ip++ = myInstanceId;
            *sp.ip++ = myCookie;
            return(new TrinityMessage(buf, msglen));
        }
예제 #4
0
        private unsafe void PostResponse_impl(SynReqArgs args)
        {
            /******************************
            * Protocol: PostResponse
            * Request: |4B InstanceId|4B Cookie|8B p| TrinityResponse |
            * Response: VOID
            ******************************/
            PointerHelper sp         = PointerHelper.New(args.Buffer + args.Offset);
            int           instanceId = *sp.ip++;
            int           cookie     = *sp.ip++;
            long          p          = *sp.lp++;
            var           stg        = CheckInstanceCookie(cookie, instanceId);

            stg.PostResponse_impl(p, sp.bp, args.Size - sizeof(int) * 2 - sizeof(long));
        }
예제 #5
0
        internal static bool GetCommunicationModuleOffset(this IMessagePassingEndpoint storage, string moduleName, out ushort synReqOffset, out ushort synReqRspOffset, out ushort asynReqOffset, out ushort asynReqRspOffset)
        {
            /******************
            * Comm. protocol:
            *  - REQUEST : [char_cnt, char[] moduleName]
            *  - RESPONSE: [int synReqOffset, int synReqRspOffset, int asynReqOffset, int asynReqRspOffset]
            * An response error code other than E_SUCCESS indicates failure of remote module lookup.
            ******************/

            using (TrinityMessage tm = new TrinityMessage(
                       TrinityMessageType.PRESERVED_SYNC_WITH_RSP,
                       (ushort)RequestType.GetCommunicationModuleOffsets,
                       size: sizeof(int) + sizeof(char) * moduleName.Length))
            {
                PointerHelper sp = PointerHelper.New(tm.Buffer + TrinityMessage.Offset);
                *sp.ip++         = moduleName.Length;

                BitHelper.WriteString(moduleName, sp.bp);
                TrinityResponse response;
                storage.SendMessage(tm, out response);
                bool ret = (response.ErrorCode == TrinityErrorCode.E_SUCCESS);
                if (ret)
                {
                    sp.bp = response.Buffer + response.Offset;
                    int synReq_msg     = *sp.ip++;
                    int synReqRsp_msg  = *sp.ip++;
                    int asynReq_msg    = *sp.ip++;
                    int asynReqRsp_msg = *sp.ip++;

                    synReqOffset     = (ushort)synReq_msg;
                    synReqRspOffset  = (ushort)synReqRsp_msg;
                    asynReqOffset    = (ushort)asynReq_msg;
                    asynReqRspOffset = (ushort)asynReqRsp_msg;
                }
                else
                {
                    synReqOffset     = 0;
                    synReqRspOffset  = 0;
                    asynReqOffset    = 0;
                    asynReqRspOffset = 0;
                }


                response.Dispose();
                return(ret);
            }
        }
예제 #6
0
        private unsafe void RedirectMessage_impl(SynReqArgs args)
        {
            /******************************
            * Protocol: RedirectMessage
            * Request: |4B PartitionId| TrinityMessage |
            * Response: VOID
            *
            * Redirects the message to another instance.
            ******************************/

            PointerHelper sp          = PointerHelper.New(args.Buffer + args.Offset);
            int           partitionId = *sp.ip++;

            TrinityMessage tm = new TrinityMessage(sp.bp, (*sp.ip) + TrinityProtocol.SocketMsgHeader);

            m_memorycloud[partitionId].SendMessage(tm);
        }
예제 #7
0
        private unsafe void RedirectMessage_impl(SynReqArgs args)
        {
            /******************************
            * Protocol: RedirectMessage
            * Request: |4B InstanceId| TrinityMessage |
            * Response: VOID
            *
            * Redirects the message to another instance.
            ******************************/

            PointerHelper sp         = PointerHelper.New(args.Buffer + args.Offset);
            int           instanceId = *sp.ip++;

            TrinityMessage tm = new TrinityMessage(sp.bp, *sp.ip + sizeof(int));

            m_memorycloud[instanceId].SendMessage(tm);
        }
예제 #8
0
        private unsafe void UpdateCell_impl(SynReqRspArgs args)
        {
            /******************************
            * Protocol: UpdateCell
            * Request: |8B CellId|4B Size| Payload |
            * Response: [ 4B TrinityErrorCode header ]
            ******************************/
            var sp   = PointerHelper.New(args.Buffer + args.Offset);
            var id   = *sp.lp++;
            var size = *sp.ip++;

            var err = (int)m_memorycloud.UpdateCell(id, sp.bp, size);
            var buf = (byte *)Memory.malloc(TrinityProtocol.MsgHeader);

            sp = PointerHelper.New(buf);
            *sp.ip++ = TrinityProtocol.MsgHeader - TrinityProtocol.SocketMsgHeader;
            *sp.ip   = err;
            args.Response = new TrinityMessage(buf, TrinityProtocol.MsgHeader);
        }
예제 #9
0
        public unsafe void SendMessage(byte *message, int size, out TrinityResponse response)
        {
            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_WITH_RSP;
            *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.RedirectMessageWithResponse;
            *(int *)(sp.bp + TrinityProtocol.MsgHeader)      = partitionId;

            m_mod.SendMessage(m_ep, bufs, sizes, 2, out response);
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
        public unsafe void SendMessage(byte **_bufs, int *_sizes, int count, out TrinityResponse response)
        {
            byte * header    = stackalloc byte[TrinityProtocol.MsgHeader + sizeof(int)];
            ulong  bufs_len  = (ulong)(sizeof(byte *) * (count + 1));
            ulong  sizes_len = (ulong)(sizeof(int) * (count + 1));
            byte **bufs      = (byte **)Memory.malloc(bufs_len);
            int *  sizes     = (int *)Memory.malloc(sizes_len);

            bufs[0]  = header;
            sizes[0] = TrinityProtocol.MsgHeader + sizeof(int);
            Memory.memcpy(bufs + 1, _bufs, bufs_len);
            Memory.memcpy(sizes + 1, _sizes, sizes_len);

            PointerHelper sp = PointerHelper.New(header);

            *sp.ip = sizeof(int) + TrinityProtocol.TrinityMsgHeader + Utils._sum(_sizes, count);
            *(sp.bp + TrinityProtocol.MsgTypeOffset)         = (byte)TrinityMessageType.SYNC_WITH_RSP;
            *(ushort *)(sp.bp + TrinityProtocol.MsgIdOffset) = (ushort)TSL.CommunicationModule.TrinityClientModule.SynReqRspMessageType.RedirectMessageWithResponse;
            *(int *)(sp.bp + TrinityProtocol.MsgHeader)      = partitionId;

            m_mod.SendMessage(m_ep, bufs, sizes, count + 1, out response);
        }
예제 #12
0
        public static InMemoryDataChunk New(IEnumerable <CellInfo> cells, int estimated_size)
        {
            MemoryStream ms = new MemoryStream(estimated_size);

            byte[] buf = new byte[sizeof(long) + sizeof(ushort) + sizeof(int)];
            byte[] buf_cell = new byte[1024];
            long   lowkey = 0, highkey = 0;
            int    size = 0;

            fixed(byte *p = buf)
            {
                foreach (var cell in cells)
                {
                    if (size == 0)
                    {
                        lowkey = cell.CellId;
                    }
                    highkey = cell.CellId;
                    PointerHelper sp = PointerHelper.New(p);
                    *sp.lp++         = cell.CellId;
                    *sp.sp++         = (short)cell.CellType;
                    *sp.ip++         = cell.CellSize;
                    ms.Write(buf, 0, buf.Length);
                    while (buf_cell.Length < cell.CellSize)
                    {
                        buf_cell = new byte[buf_cell.Length * 2];
                    }
                    Memory.Copy(cell.CellPtr, 0, buf_cell, 0, cell.CellSize);
                    ms.Write(buf_cell, 0, cell.CellSize);
                    size += cell.CellSize + buf.Length;
                }
            }

            byte[] payload = ms.GetBuffer();
            Chunk  chunk   = new Chunk(lowkey, highkey);

            return(new InMemoryDataChunk(chunk, payload, lowkey, highkey));
        }
예제 #13
0
        private unsafe TrinityErrorCode _SendCellPayload(long cellId, byte *buff, int size, ushort?cellType, short msgId)
        {
            //header: cellId, size, type
            int           header_len = TrinityProtocol.MsgHeader + sizeof(long) + sizeof(int) + (cellType.HasValue? sizeof(ushort): 0);
            byte *        header     = stackalloc byte[header_len];
            byte **       holder     = stackalloc byte *[2];
            int *         length     = stackalloc int[2];
            PointerHelper sp         = PointerHelper.New(header);

            *sp.ip++ = header_len + size - TrinityProtocol.SocketMsgHeader;
            *sp.sp++ = (short)TrinityMessageType.SYNC_WITH_RSP;
            *sp.sp++ = msgId;
            *sp.lp++ = cellId;
            *sp.ip++ = size;

            if (cellType.HasValue)
            {
                *sp.sp++ = (short)cellType;
            }

            holder[0] = header;
            holder[1] = buff;
            length[0] = header_len;
            length[1] = size;

            TrinityResponse rsp = null;

            try
            {
                m_mod.SendMessage(m_ep, holder, length, 2, out rsp);
                return(*(TrinityErrorCode *)(rsp.Buffer));
            }
            finally
            {
                rsp?.Dispose();
            }
        }
예제 #14
0
        internal static void GetCommunicationSchema(this IMessagePassingEndpoint storage, out string name, out string signature)
        {
            /******************
            * Comm. protocol:
            *  - REQUEST : VOID
            *  - RESPONSE: [char_cnt, char[] name, char_cnt, char[] sig]
            ******************/
            using (TrinityMessage tm = new TrinityMessage(
                       TrinityMessageType.PRESERVED_SYNC_WITH_RSP,
                       (ushort)RequestType.GetCommunicationSchema,
                       size: 0))
            {
                TrinityResponse response;
                storage.SendMessage(tm, out response);
                PointerHelper sp = PointerHelper.New(response.Buffer + response.Offset);
                int           name_string_len = *sp.ip++;
                name   = BitHelper.GetString(sp.bp, name_string_len * 2);
                sp.cp += name_string_len;
                int sig_string_len = *sp.ip++;
                signature = BitHelper.GetString(sp.bp, sig_string_len * 2);

                response.Dispose();
            }
        }