Exemple #1
0
        static void RpcCallback <T>(IntPtr userData, IntPtr err, IntPtr responseBuf)
        {
            var handle  = GCHandle.FromIntPtr(userData);
            var context = (CallbackContext <T>)handle.Target;

            if (err != IntPtr.Zero)
            {
                var pitayaError = new PitayaError(
                    PitayaCluster.pitaya_error_code(err),
                    PitayaCluster.pitaya_error_message(err));
                context.t.SetException(new PitayaException($"RPC call failed: ({pitayaError.Code}: {pitayaError.Message})"));
                return;
            }

            Int32  len;
            IntPtr resData = PitayaCluster.pitaya_buffer_data(responseBuf, out len);

            byte[] resBytes = GetDataFromRawPointer(resData, len);

            try
            {
                // An RPC message comes encoded as a Protos.Response protobuf message.
                // The data field of the message is going to be either encoded in protobuf or JSON,
                // which is taken care by our serializer variable

                var rpcResponse = new Protos.Response();
                rpcResponse.MergeFrom(resBytes);

                if (rpcResponse.Error == null)
                {
                    T remoteResponse = (T)context.serializer.Unmarshal(rpcResponse.Data.ToByteArray(), typeof(T));
                    context.t.SetResult(remoteResponse);
                }
                else
                {
                    context.t.SetException(new PitayaException(
                                               "rpc failed: code={0} msg={1}",
                                               rpcResponse.Error.Code, rpcResponse.Error.Msg
                                               ));
                }
            }
            catch (Exception e)
            {
                context.t.SetException(new PitayaException(
                                           "failed to parse rpc response: {0} (payload={1})",
                                           e.Message, Encoding.UTF8.GetString(resBytes)
                                           ));
            }
        }
Exemple #2
0
        static void DispatchRpc(RpcClient rpcClient, IntPtr rpc, Protos.Request req)
        {
            Task.Run(async() => {
                var start = Stopwatch.StartNew();
                var res   = new Protos.Response();
                try
                {
                    res = await HandleRpc(rpcClient, req, req.Type);
                }
                catch (Exception e)
                {
                    res = GetErrorResponse("PIT-500", e.Message);

                    var innerMostException = e;
                    while (innerMostException.InnerException != null)
                    {
                        innerMostException = innerMostException.InnerException;
                    }

                    Logger.Error("Exception thrown in handler: {0}", innerMostException.Message);
#if NPITAYA_DEBUG
                    Logger.Error("StackTrace: {0}", e.StackTrace);
#endif
                }
                finally
                {
                    start.Stop();
                    _metricsReporter?.ObserveHistogram(RPC_LATENCY_METRIC, (float)start.Elapsed.TotalSeconds, null);
                    unsafe
                    {
                        byte[] responseData = res.ToByteArray();
                        Int32 responseLen   = responseData.Length;

                        fixed(byte *p = responseData)
                        {
                            IntPtr err = pitaya_rpc_respond(rpc, (IntPtr)p, responseLen);
                            if (err != IntPtr.Zero)
                            {
                                pitaya_error_drop(err);
                                Logger.Error("Failed to respond to rpc");
                            }
                        }
                    }
                }
            });
        }
        static void DispatchRpc(RpcClient rpcClient, IntPtr rpc, Protos.Request req)
        {
            Task.Run(async() => {
                var res = new Protos.Response();
                try
                {
                    res = await HandleRpc(rpcClient, req, req.Type);
                }
                catch (Exception e)
                {
                    res = GetErrorResponse("PIT-500", e.Message);

                    var innerMostException = e;
                    while (innerMostException.InnerException != null)
                    {
                        innerMostException = innerMostException.InnerException;
                    }

                    Logger.Error("Exception thrown in handler: {0}", innerMostException.Message);
#if NPITAYA_DEBUG
                    Logger.Error("StackTrace: {0}", e.StackTrace);
#endif
                }
                finally
                {
                    unsafe
                    {
                        byte[] responseData = res.ToByteArray();
                        Int32 responseLen   = responseData.Length;

                        fixed(byte *p = responseData)
                        {
                            IntPtr err = pitaya_rpc_respond(rpc, (IntPtr)p, responseLen);
                            if (err != IntPtr.Zero)
                            {
                                pitaya_error_drop(err);
                                Logger.Error("Failed to respond to rpc");
                            }
                        }
                    }
                }
            });
        }