in rd-net/RdFramework/Tasks/WiredRdTask.cs [145:200]
public Endpoint(Lifetime bindLifetime, RdCall<TReq, TRes> call, RdId rdId, IScheduler wireScheduler) : base(call, rdId, wireScheduler)
{
myDef = bindLifetime.CreateNested();
myDef.Id = this;
Wire?.Advise(Lifetime, this);
Lifetime.TryOnTermination(() => ResultInternal.SetIfEmpty(RdTaskResult<TRes>.Cancelled()));
if (!TryGetSerializationContext(out var serializationCtx))
return;
Result.AdviseOnce(Lifetime.Eternal, taskResult =>
{
var proto = myCall.TryGetProto();
var potentiallyBindable = taskResult.Result;
if (potentiallyBindable.IsBindable())
{
if (proto == null)
{
Wire?.Send(RdId, writer => { RdTaskResult<TRes>.Write(myCall.WriteResponseDelegate, serializationCtx, writer, RdTaskResult<TRes>.Cancelled()); });
return;
}
potentiallyBindable.IdentifyPolymorphic(proto.Identities, myCall.RdId.Mix(RdId.ToString()));
using var cookie = Lifetime.UsingExecuteIfAlive();
if (cookie.Succeed) // lifetime can be terminated from background thread
{
potentiallyBindable.PreBindPolymorphic(Lifetime, myCall, RdId.ToString());
if (Lifetime.IsNotAlive)
return;
Wire?.Send(RdId, writer =>
{
RdTaskResult<TRes>.Write(myCall.WriteResponseDelegate, serializationCtx, writer, taskResult);
});
if (Lifetime.IsNotAlive)
return;
potentiallyBindable.BindPolymorphic();
}
}
else
{
myDef.Terminate();
Wire?.Send(RdId,
writer =>
{
RdTaskResult<TRes>.Write(myCall.WriteResponseDelegate, serializationCtx, writer, taskResult);
});
}
Trace(RdReactiveBase.ourLogSend, "send response", taskResult);
});
}