Ejemplo n.º 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);
                    });
                });
            }
Ejemplo n.º 2
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();
                    }
                });
            }
Ejemplo n.º 3
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
            });
        }
Ejemplo n.º 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();
     }
 }
Ejemplo n.º 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);
        }
Ejemplo n.º 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");
                    }
                }
            }
Ejemplo n.º 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
                }
            });
        }
Ejemplo n.º 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");
                    }
                }
            }
        }