//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 }); }
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); }); }); }
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(); } }
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); }
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"); } } }
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 } }); }
//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"); } } } }
/// <summary> /// Construct a successful result /// </summary> protected ResultAbstract() { _internalResult = new ResultInternal(); }
/// <summary> /// Construct a failed result /// </summary> protected ResultAbstract(IEnumerable <IFailure> failures) { _internalResult = new ResultInternal(failures); }