Example #1
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();
                    }
                });
            }
Example #2
0
 public void Print(PrettyPrinter printer)
 {
     printer.Print(ToString());
     printer.Print("(");
     printer.Print(RdId.ToString());
     printer.Print(")");
 }
Example #3
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);
                    });
                });
            }
Example #4
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
            outerLifetime.TryOnTermination(() => ResultInternal.SetIfEmpty(RdTaskResult <TRes> .Cancelled())); //todo

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

                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());
                }

                if (myIsEndpoint)
                {
                    if (taskResult.Status == RdTaskStatus.Canceled)
                    {
                        externalCancellation.Terminate();
                    }

                    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
                }
            });

            return(externalCancellation.Lifetime);
        }