示例#1
0
文件: RdCall.cs 项目: Tryweirder/rd
        public override void OnWireReceived(UnsafeReader reader) //endpoint's side
        {
            var taskId = RdId.Read(reader);

            var wiredTask = new WiredRdTask <TReq, TRes> .Endpoint(myBindLifetime, this, taskId, myCancellationScheduler ?? SynchronousScheduler.Instance);

            //subscribe for lifetime cancellation
            var externalCancellation = wiredTask.Lifetime;

            using (UsingDebugInfo()) //now supports only sync handlers
            {
                RdTask <TRes> rdTask;
                try
                {
                    var value = ReadRequestDelegate(SerializationContext, reader);
                    ReceiveTrace?.Log($"{wiredTask} :: received request: {value.PrintToString()}");
                    var handler = Handler;
                    if (handler == null)
                    {
                        var message = $"Handler is not set for {wiredTask} :: received request: {value.PrintToString()}";
                        ourLogReceived.Error(message);
                        rdTask = RdTask <TRes> .Faulted(new Exception(message));
                    }
                    else
                    {
                        try
                        {
                            rdTask = handler(externalCancellation, value);
                        }
                        catch (Exception ex)
                        {
                            rdTask = RdTask <TRes> .Faulted(ex);
                        }
                    }
                }
                catch (Exception e)
                {
                    rdTask = RdTask <TRes> .Faulted(new Exception($"Unexpected exception in {wiredTask}", e));
                }

                rdTask.Result.Advise(Lifetime.Eternal, result =>
                {
                    try
                    {
                        if (result.Status == RdTaskStatus.Success)
                        {
                            AssertNullability(result.Result);
                        }

                        wiredTask.ResultInternal.SetIfEmpty(result);
                    }
                    catch (Exception ee)
                    {
                        ourLogSend.Error($"Problem when responding to `{wiredTask}`", ee);
                        wiredTask.Set(new RdFault(ee));
                    }
                });
            }
        }
示例#2
0
        public override void OnWireReceived(UnsafeReader reader)
        {
            var taskId = RdId.Read(reader);
            var value  = ReadRequestDelegate(SerializationContext, reader);

            if (LogReceived.IsTraceEnabled())
            {
                LogReceived.Trace("endpoint `{0}`::({1}), taskId={2}, request = {3}", Location, RdId, taskId, value.PrintToString());
            }


            RdTask <TRes> rdTask;

            using (UsingDebugInfo()) //now supports only sync handlers
            {
                try
                {
                    rdTask = Handler(myBindLifetime, value);
                }
                catch (OperationCanceledException)
                {
                    rdTask = RdTask <TRes> .Cancelled();
                }
                catch (Exception e)
                {
                    rdTask = RdTask <TRes> .Faulted(e);
                }
            }

            rdTask.Result.Advise(myBindLifetime, result =>
            {
                if (LogSend.IsTraceEnabled())
                {
                    LogSend.Trace("endpoint `{0}`::({1}), taskId={2}, response = {3}", Location, RdId, taskId, result.PrintToString());
                }

                RdTaskResult <TRes> validatedResult;
                try
                {
                    if (result.Status == RdTaskStatus.Success)
                    {
                        AssertNullability(result.Result);
                    }
                    validatedResult = result;
                }
                catch (Exception e)
                {
                    LogSend.Error(e);
                    validatedResult = RdTaskResult <TRes> .Faulted(e);
                }

                Wire.Send(RdId, (writer) =>
                {
                    taskId.Write(writer);
                    RdTaskResult <TRes> .Write(WriteResponseDelegate, SerializationContext, writer, validatedResult);
                });
            });
        }
示例#3
0
        private static unsafe void Execute(IRdReactive reactive, byte[] msg)
        {
            fixed(byte *p = msg)
            {
                var reader = UnsafeReader.CreateReader(p, msg.Length);
                var rdid0  = RdId.Read(reader);

                Assertion.Assert(reactive.RdId.Equals(rdid0), "Not equals: {0}, {1}", reactive.RdId, rdid0);

                reactive.OnWireReceived(reader);
            }
        }
示例#4
0
        private static unsafe void Execute(IRdWireable reactive, byte[] msg)
        {
            fixed(byte *p = msg)
            {
                var reader = UnsafeReader.CreateReader(p, msg.Length);
                var rdid0  = RdId.Read(reader);

                Assertion.Assert(reactive.RdId.Equals(rdid0), "Not equals: {0}, {1}", reactive.RdId, rdid0);

                using (reactive.Proto.Contexts.ReadContextsIntoCookie(reader))
                    reactive.OnWireReceived(reader);
            }
        }
示例#5
0
        public T Read <T>(SerializationCtx ctx, UnsafeReader reader, [CanBeNull] CtxReadDelegate <T> unknownInstanceReader = null)
        {
            bool TryGetReader(RdId rdId, out CtxReadDelegate <object> readDelegate)
            {
                lock (myLock)
                    return(myReaders.TryGetValue(rdId, out readDelegate));
            }

#if !NET35
            myBackgroundRegistrar.WaitForEmpty();
#endif

            var typeId = RdId.Read(reader);
            if (typeId.IsNil)
            {
                return(default(T));
            }
            var size = reader.ReadInt();

            if (!TryGetReader(typeId, out var ctxReadDelegate))
            {
                if (unknownInstanceReader == null)
                {
                    myRegistrar?.TryRegister(typeId, this);
                    myRegistrar?.TryRegister(typeof(T), this);
                    if (!TryGetReader(typeId, out ctxReadDelegate))
                    {
                        var realType = myTypeMapping.SingleOrDefault(c => Equals(c.Value, typeId)); //ok because it's rarely needed
                        throw new KeyNotFoundException(string.Format("There is no readers found. Requested type '{0}'. Real type {1}", typeof(T).FullName, realType));
                    }
                }
                else
                {
                    var objectStart = reader.Position;
                    var result      = unknownInstanceReader(ctx, reader);
                    var bytesRead   = reader.Position - objectStart;
                    reader.Skip(size - bytesRead);
                    return(result);
                }
            }

            var uncasted = ctxReadDelegate(ctx, reader);
            Assertion.Assert(uncasted is T, "Bad cast for id {0}. Expected: {1}, actual: {2}", typeId, typeof(T).Name, uncasted.GetType().Name);
            return((T)uncasted);
        }
示例#6
0
        public override void OnWireReceived(UnsafeReader reader) //endpoint's side
        {
            var taskId = RdId.Read(reader);

            var wiredTask = new WiredRdTask <TReq, TRes>(this, taskId, myEndpointSchedulerForHandlerAndCancellation ?? WireScheduler, true);
            //subscribe for lifetime cancellation
            var externalCancellation = wiredTask.Subscribe(myBindLifetime);

            using (UsingDebugInfo()) //now supports only sync handlers
            {
                RdTask <TRes> rdTask;
                try
                {
                    var value = ReadRequestDelegate(SerializationContext, reader);
                    ReceiveTrace?.Log($"{wiredTask} :: received request: {value.PrintToString()}");
                    rdTask = Handler(externalCancellation, value);
                }
                catch (Exception e)
                {
                    rdTask = RdTask <TRes> .Faulted(e);
                }

                rdTask.Result.Advise(Lifetime.Eternal, result =>
                {
                    try
                    {
                        if (result.Status == RdTaskStatus.Success)
                        {
                            AssertNullability(result.Result);
                        }

                        wiredTask.ResultInternal.SetIfEmpty(result);
                    }
                    catch (Exception ee)
                    {
                        ourLogSend.Error($"Problem when responding to `{wiredTask}`", ee);
                        wiredTask.Set(new RdFault(ee));
                    }
                });
            }
        }
示例#7
0
 public static RdId ReadRdId(this UnsafeReader reader)
 {
     return(RdId.Read(reader));
 }
示例#8
0
        public override void OnWireReceived(UnsafeReader reader)
        {
            var taskId = RdId.Read(reader);
            var value  = ReadRequestDelegate(SerializationContext, reader);

            if (LogReceived.IsTraceEnabled())
            {
                LogReceived.Trace("endpoint `{0}`::({1}), taskId={2}, request = {3}", Location, RdId, taskId, value.PrintToString());
            }


            var taskLifetimeDef = myBindLifetime.CreateNested();

            //subscribe for lifetime cancellation
            new WiredLifetime(taskLifetimeDef, taskId, this, Wire);

            RdTask <TRes> rdTask;

            using (UsingDebugInfo()) //now supports only sync handlers
            {
                try
                {
                    rdTask = Handler(taskLifetimeDef.Lifetime, value);
                }
                catch (Exception e)
                {
                    rdTask = RdTask <TRes> .Faulted(e);
                }
            }



            rdTask.Result.Advise(taskLifetimeDef.Lifetime, result =>
            {
                if (LogSend.IsTraceEnabled())
                {
                    LogSend.Trace("endpoint `{0}`::({1}), taskId={2}, response = {3}", Location, RdId, taskId, result.PrintToString());
                }

                RdTaskResult <TRes> validatedResult;
                try
                {
                    if (result.Status == RdTaskStatus.Success)
                    {
                        AssertNullability(result.Result);
                    }
                    validatedResult = result;
                }
                catch (Exception e)
                {
                    LogSend.Error(e);
                    validatedResult = RdTaskResult <TRes> .Faulted(e);
                }

                Wire.Send(taskId, writer =>
                {
                    RdTaskResult <TRes> .Write(WriteResponseDelegate, SerializationContext, writer, validatedResult);
                });

                taskLifetimeDef.Terminate(); //need to terminate to unsubscribe lifetime listener - not for bindable entries
            });
        }