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 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); }); }); }
protected WiredRdTask(RdCall <TReq, TRes> call, RdId rdId, IScheduler wireScheduler) { myCall = call; RdId = rdId; WireScheduler = wireScheduler; myWire = call.Wire; Location = call.Location.Sub(rdId); }
public WiredRdTask(RdCall <TReq, TRes> call, RdId rdId, IScheduler wireScheduler, bool isEndpoint) { myCall = call; myIsEndpoint = isEndpoint; RdId = rdId; WireScheduler = wireScheduler; myWire = call.Wire; Location = call.Location.Sub(rdId); }
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 } }); }
public static void Write(SerializationCtx ctx, UnsafeWriter writer, RdCall <TReq, TRes> value) { value.RdId.Write(writer); }