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(); } }); }
public void Print(PrettyPrinter printer) { printer.Print(ToString()); printer.Print("("); printer.Print(RdId.ToString()); printer.Print(")"); }
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); }); }); }
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); }