示例#1
0
            public Endpoint(Lifetime bindLifetime, RdCall <TReq, TRes> call, RdId rdId, IScheduler wireScheduler) : base(call, rdId, wireScheduler)
            {
                myDef = bindLifetime.CreateNested();

                myCall.Wire.Advise(Lifetime, this);
                Lifetime.TryOnTermination(() => ResultInternal.SetIfEmpty(RdTaskResult <TRes> .Cancelled()));

                Result.AdviseOnce(Lifetime.Eternal, taskResult =>
                {
                    var potentiallyBindable = taskResult.Result;
                    if (potentiallyBindable.IsBindable())
                    {
                        potentiallyBindable.IdentifyPolymorphic(myCall.Proto.Identities, myCall.RdId.Mix(RdId.ToString()));
                        potentiallyBindable.BindPolymorphic(Lifetime, myCall, RdId.ToString());
                    }
                    else
                    {
                        myDef.Terminate();
                    }

                    Trace(RdReactiveBase.ourLogSend, "send response", taskResult);
                    myWire.Send(RdId,
                                writer =>
                    {
                        RdTaskResult <TRes> .Write(myCall.WriteResponseDelegate, myCall.SerializationContext, writer, taskResult);
                    });
                });
            }
示例#2
0
        //received response from wire
        public void OnWireReceived(UnsafeReader reader)
        {
            var resultFromWire = RdTaskResult <TRes> .Read(myCall.ReadResponseDelegate, myCall.SerializationContext, reader);

            if (RdReactiveBase.LogReceived.IsTraceEnabled())
            {
                RdReactiveBase.LogReceived.Trace($"call {myCall.Location} ({myCall.RdId}) received response for task '{RdId}' : {resultFromWire.PrintToString()}");
            }

            Scheduler.Queue(() =>
            {
                using (myCall.UsingDebugInfo())
                {
                    if (ResultInternal.SetIfEmpty(resultFromWire))
                    {
                        return;
                    }
                }

                //trace
                if (RdReactiveBase.LogReceived.IsTraceEnabled())
                {
                    RdReactiveBase.LogReceived.Trace($"call {myCall.Location} ({myCall.RdId}) response for task '{RdId}' was dropped, because task already has result: {Result.Value}");
                }

                myLifetimeDef.Terminate(); //todo not true in case of bindable entities
            });
        }
示例#3
0
文件: RdTask.cs 项目: yvvan/rd
        private static RdTask <T> FromResult(RdTaskResult <T> result)
        {
            var res = new RdTask <T>();

            res.ResultInternal.Value = result;
            return(res);
        }
示例#4
0
 public override void OnWireReceived(UnsafeReader reader)
 {
     using (myCall.UsingDebugInfo())
     {
         //we are on endpoint side, so listening for cancellation
         Trace(RdReactiveBase.ourLogReceived, "received cancellation");
         reader.ReadVoid(); //nothing just a void value
         ResultInternal.SetIfEmpty(RdTaskResult <TRes> .Cancelled());
         myDef.Terminate();
     }
 }
示例#5
0
        internal Lifetime Subscribe(Lifetime outerLifetime)
        {
            var taskWireSubscriptionDefinition = outerLifetime.CreateNested();
            var externalCancellation           = outerLifetime.CreateNested();

            myCall.Wire.Advise(taskWireSubscriptionDefinition.Lifetime, this); //this lifetimeDef listen only one value
            taskWireSubscriptionDefinition.Lifetime.TryOnTermination(() => ResultInternal.SetIfEmpty(RdTaskResult <TRes> .Cancelled()));

            Result.AdviseOnce(Lifetime.Eternal, taskResult =>
            {
                try
                {
                    var potentiallyBindable = taskResult.Result;
                    if (potentiallyBindable.IsBindable())
                    {
                        if (myIsEndpoint)
                        {
                            potentiallyBindable.IdentifyPolymorphic(myCall.Proto.Identities, myCall.RdId.Mix(RdId.ToString()));
                        }

                        potentiallyBindable.BindPolymorphic(externalCancellation.Lifetime, myCall, RdId.ToString());
                    }
                    else
                    {
                        externalCancellation.Terminate();
                    }

                    if (myIsEndpoint)
                    {
                        Trace(RdReactiveBase.ourLogSend, "send response", taskResult);
                        myWire.Send(RdId,
                                    writer =>
                        {
                            RdTaskResult <TRes> .Write(myCall.WriteResponseDelegate, myCall.SerializationContext, writer, taskResult);
                        });
                    }
                    else if (taskResult.Status == RdTaskStatus.Canceled) //we need to transfer cancellation to the other side
                    {
                        Trace(RdReactiveBase.ourLogSend, "send cancellation");
                        myWire.Send(RdId, writer => { writer.Write(Unit.Instance); }); //send cancellation to the other side
                    }
                }
                finally
                {
                    taskWireSubscriptionDefinition.Terminate(); //no need to listen result or cancellation from wire
                }
            });

            return(externalCancellation.Lifetime);
        }
示例#6
0
            public override void OnWireReceived(UnsafeReader reader)
            {
                using (myCall.UsingDebugInfo())
                {
                    // we are at call side, so listening no response and bind it if it's bindable
                    var resultFromWire = RdTaskResult <TRes> .Read(myCall.ReadResponseDelegate, myCall.SerializationContext, reader);

                    Trace(RdReactiveBase.ourLogReceived, "received response", resultFromWire);

                    if (!ResultInternal.SetIfEmpty(resultFromWire))
                    {
                        Trace(RdReactiveBase.ourLogReceived, "response from wire was rejected because task already has result");
                    }
                }
            }
示例#7
0
        public WiredRdTask(LifetimeDefinition lifetimeDef, RdCall <TReq, TRes> call, RdId rdId, IScheduler scheduler)
        {
            myLifetimeDef = lifetimeDef;
            myCall        = call;
            RdId          = rdId;
            Scheduler     = scheduler;
            myWire        = call.Wire;

            call.Wire.Advise(lifetimeDef.Lifetime, this);
            lifetimeDef.Lifetime.TryOnTermination(() =>
            {
                //otherwise it could be successful continuation from Queue
                if (ResultInternal.SetIfEmpty(RdTaskResult <TRes> .Cancelled()))
                {
                    RdReactiveBase.LogSend.Trace($"call {myCall.Location} ({myCall.RdId}) send cancellation for task '{RdId}'");
                    myWire.Send(rdId, writer => { writer.Write(Unit.Instance); }); //send cancellation to the other side
                }
            });
        }
示例#8
0
        //received response from wire
        public void OnWireReceived(UnsafeReader reader)
        {
            using (myCall.UsingDebugInfo())
            {
                if (myIsEndpoint) //we are on endpoint side, so listening for cancellation
                {
                    Trace(RdReactiveBase.ourLogReceived, "received cancellation");
                    reader.ReadVoid(); //nothing just a void value
                    ResultInternal.SetIfEmpty(RdTaskResult <TRes> .Cancelled());
                }

                else // we are at call side, so listening no response and bind it if it's bindable
                {
                    var resultFromWire = RdTaskResult <TRes> .Read(myCall.ReadResponseDelegate, myCall.SerializationContext, reader);

                    Trace(RdReactiveBase.ourLogReceived, "received response", resultFromWire);

                    if (!ResultInternal.SetIfEmpty(resultFromWire))
                    {
                        Trace(RdReactiveBase.ourLogReceived, "response from wire was rejected because task already has result");
                    }
                }
            }
        }
示例#9
0
 public static RdTask <T> Cancelled()
 {
     return(FromResult(RdTaskResult <T> .Cancelled()));
 }
示例#10
0
 public void Set(T value) => ResultInternal.Value     = RdTaskResult <T> .Success(value);
示例#11
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
            });
        }
示例#12
0
文件: RdTaskResult.cs 项目: yvvan/rd
        public static void Write(CtxWriteDelegate <T> writeDelegate, SerializationCtx ctx, UnsafeWriter writer, RdTaskResult <T> value)
        {
            writer.Write((int)value.Status);

            switch (value.Status)
            {
            case RdTaskStatus.Success:
                writeDelegate(ctx, writer, value.Result);
                break;

            case RdTaskStatus.Canceled:
                break;

            case RdTaskStatus.Faulted:
                RdFault.Write(ctx, writer, value.Error);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
示例#13
0
 public void SetCancelled() => ResultInternal.Value   = RdTaskResult <T> .Cancelled();
示例#14
0
 public void Set(Exception e) => ResultInternal.Value = RdTaskResult <T> .Faulted(e);
示例#15
0
文件: RdTask.cs 项目: yvvan/rd
 public static RdTask <T> Faulted(Exception exception) => FromResult(RdTaskResult <T> .Faulted(exception));
示例#16
0
文件: RdTask.cs 项目: yvvan/rd
 public static RdTask <T> Successful(T result) => FromResult(RdTaskResult <T> .Success(result));
示例#17
0
 public static RdTask <T> Faulted(Exception exception)
 {
     return(FromResult(RdTaskResult <T> .Faulted(exception)));
 }
示例#18
0
文件: RdTask.cs 项目: yvvan/rd
 public void Set(Exception e) => ResultInternal.SetIfEmpty(RdTaskResult <T> .Faulted(e));
示例#19
0
文件: RdTask.cs 项目: yvvan/rd
 public void SetCancelled() => ResultInternal.SetIfEmpty(RdTaskResult <T> .Cancelled());
示例#20
0
文件: RdTask.cs 项目: yvvan/rd
 public void Set(T value) => ResultInternal.SetIfEmpty(RdTaskResult <T> .Success(value));
示例#21
0
            public CallSite(Lifetime outerLifetime, RdCall <TReq, TRes> call, RdId rdId, IScheduler wireScheduler) : base(call, rdId, wireScheduler)
            {
                var taskWireSubscriptionDefinition = outerLifetime.CreateNested();

                myCall.Wire.Advise(taskWireSubscriptionDefinition.Lifetime, this); //this lifetimeDef listen only one value
                taskWireSubscriptionDefinition.Lifetime.TryOnTermination(() => ResultInternal.SetIfEmpty(RdTaskResult <TRes> .Cancelled()));

                Result.AdviseOnce(Lifetime.Eternal, taskResult =>
                {
                    taskWireSubscriptionDefinition.Terminate(); //no need to listen result or cancellation from wire

                    var potentiallyBindable = taskResult.Result;
                    if (potentiallyBindable.IsBindable())
                    {
                        potentiallyBindable.BindPolymorphic(outerLifetime, myCall, RdId.ToString());
                        if (!outerLifetime.TryOnTermination(SendCancellation))
                        {
                            SendCancellation();
                        }
                    }
                    else if (taskResult.Status == RdTaskStatus.Canceled) //we need to transfer cancellation to the other side
                    {
                        SendCancellation();
                    }
                });
            }
示例#22
0
 public static RdTask <T> Successful(T result)
 {
     return(FromResult(RdTaskResult <T> .Success(result)));
 }
示例#23
0
文件: RdTask.cs 项目: yvvan/rd
 public static RdTask <T> Cancelled() => FromResult(RdTaskResult <T> .Cancelled());