Пример #1
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();
            }
        }
Пример #2
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();
        }
Пример #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 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();
        }
Пример #5
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();
        }
Пример #6
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("无法加入线程池");
            }
        }
Пример #7
0
        private void ProcessInvokeRequire(IMessageChannel channel, IntPtr first)
        {
            InvokeRequire require;

            try
            {
                unsafe
                {
                    require = channel.Deserialize <InvokeRequire>((MessageChunk *)first.ToPointer());
                }
            }
            catch (Exception ex)
            {
                Log.Warn($"反序列化InvokeRequire错误: {ex.Message}");
                //TODO:直接发送反序列化错误回复,需要修改Channel.Deserialize入参引用InvokeRequire
                return;
            }

            try
            {
                var enqueueOk = ThreadPool.QueueUserWorkItem(async(req) =>
                {
                    InvokeResponse response;

                    //TODO:调用服务并根据请求来源及协议进行相应的序列化后发送回Host进程
                    //Log.Debug($"收到InvokeRequire: {req.Service}");
                    //var res = await TestReadPerf();
                    //var res = await TestInsertPerf();

                    //设置会话信息后调用服务
                    Runtime.RuntimeContext.Current.CurrentSession = req.Session;
                    try
                    {
                        var res  = await Runtime.RuntimeContext.Current.InvokeAsync(req.Service, req.Args);
                        response = new InvokeResponse(req.Source, req.ContentType, req.WaitHandle, req.SourceMsgId, res);
                    }
                    catch (Exception ex)
                    {
                        response = new InvokeResponse(req.Source, req.ContentType, req.WaitHandle, req.SourceMsgId,
                                                      InvokeResponseError.ServiceInnerError, ex.Message);
                        Log.Warn($"Service internal error: {ExceptionHelper.GetExceptionDetailInfo(ex)}");
                    }
                    finally
                    {
                        req.Args.ReturnBuffer(); //注意归还由主进程封送过来的参数缓存块
                    }

                    //最后发送回复,注意:序列化失败会标记消息Flag为序列化错误
                    try
                    {
                        channel.SendMessage(ref response);
                    }
                    catch (Exception ex)
                    {
                        Log.Warn($"[AppContainer]发送回复错误: {ex.Message}");
                    }
                }, require, preferLocal: false);

                if (!enqueueOk)
                {
                    Log.Debug("无法加入线程池处理");
                }
            }
            catch (NotSupportedException)
            {
                unsafe { channel.ReturnMessageChunks((MessageChunk *)first.ToPointer()); }
                //TODO:直接发送异常回复
                Log.Warn("[AppContainer]未能加入到线程池处理InvokeRequire");
            }
        }
Пример #8
0
        private unsafe void ProcessInvalidModelsCache(IMessageChannel channel, MessageChunk *first)
        {
            var msg = channel.Deserialize <InvalidModelsCache>(first);

            Runtime.RuntimeContext.Current.InvalidModelsCache(msg.Services, msg.Models, false);
        }
Пример #9
0
        private unsafe void ProcessMetricRequire(IMessageChannel channel, MessageChunk *first)
        {
            var req = channel.Deserialize <MetricRequire>(first);

            ServerMetrics.InvokeDuration.WithLabels(req.Service).Observe(req.Value);
        }