Skip to content

Commit

Permalink
Dot not create new lifetime if requestLifetime is Eternal
Browse files Browse the repository at this point in the history
  • Loading branch information
Iliya-usov authored and ForNeVeR committed Oct 19, 2023
1 parent c5b0aa0 commit 5d6c9de
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ abstract class WiredRdTask<TReq, TRes>(
}

class CallSiteWiredRdTask<TReq, TRes>(
private val outerLifetime: Lifetime,
val outerLifetime: Lifetime,
call: RdCall<TReq, TRes>,
rdid: RdId,
wireScheduler: IScheduler
Expand Down Expand Up @@ -364,15 +364,11 @@ class RdCall<TReq, TRes>(internal val requestSzr: ISerializer<TReq> = Polymorphi


val taskId = proto.identity.next(RdId.Null)
val bindLifetime = bindLifetime
val intersectedDef = lifetime.defineIntersection(bindLifetime)
val task = CallSiteWiredRdTask(intersectedDef.lifetime, this, taskId, scheduler ?: proto.scheduler)
task.result.advise(intersectedDef.lifetime) {
if (it !is RdTaskResult.Success || !it.value.isBindable()) {
intersectedDef.terminate(true)
}
val task = createCallSite(lifetime) { callsiteLifetime ->
CallSiteWiredRdTask(callsiteLifetime, this, taskId, scheduler ?: proto.scheduler)
}
intersectedDef.lifetime.executeIfAlive {

task.outerLifetime.executeIfAlive {
proto.wire.send(rdid) { buffer ->
logSend.trace { "call `$location`::($rdid) send${sync.condstr {" SYNC"}} request '$taskId' : ${request.printToString()} " }
taskId.write(buffer)
Expand All @@ -383,6 +379,24 @@ class RdCall<TReq, TRes>(internal val requestSzr: ISerializer<TReq> = Polymorphi
return task
}

private inline fun createCallSite(
requestLifetime: Lifetime,
createTask: (Lifetime) -> CallSiteWiredRdTask<TReq, TRes>
): CallSiteWiredRdTask<TReq, TRes> {
if (requestLifetime.isEternal)
return createTask(bindLifetime)

val intersectedDef = Lifetime.defineIntersection(requestLifetime, bindLifetime)
val task = createTask(intersectedDef.lifetime)
task.result.advise(intersectedDef.lifetime) {
if (it !is RdTaskResult.Success || !it.value.isBindable()) {
intersectedDef.terminate(true)
}
}

return task
}

/**
* Assigns a handler that executes the API asynchronously.
*/
Expand Down
32 changes: 21 additions & 11 deletions rd-net/RdFramework/Tasks/RdCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,18 +200,9 @@ private IRdTask<TRes> StartInternal(Lifetime requestLifetime, TReq request, ISch

var taskId = proto.Identities.Next(RdId.Nil);

var intersectedDef = Lifetime.DefineIntersection(requestLifetime, myBindLifetime);
var task = new WiredRdTask<TReq,TRes>.CallSite(intersectedDef.Lifetime, this, taskId, scheduler ?? proto.Scheduler);
task.Result.Advise(intersectedDef.Lifetime, result =>
{
if (result.Status != RdTaskStatus.Success || !result.Result.IsBindable())
{
intersectedDef.AllowTerminationUnderExecution = true;
intersectedDef.Terminate();
}
});
var task = CreateCallSite(requestLifetime, (lifetime) => new WiredRdTask<TReq, TRes>.CallSite(lifetime, this, taskId, scheduler ?? proto.Scheduler));

using var cookie = intersectedDef.UsingExecuteIfAlive();
using var cookie = task.Lifetime.UsingExecuteIfAlive();
if (cookie.Succeed)
{
proto.Wire.Send(RdId, (writer) =>
Expand All @@ -226,6 +217,25 @@ private IRdTask<TRes> StartInternal(Lifetime requestLifetime, TReq request, ISch
return task;
}

private WiredRdTask<TReq, TRes>.CallSite CreateCallSite(Lifetime requestLifetime, Func<Lifetime, WiredRdTask<TReq, TRes>.CallSite> createTask)
{
if (requestLifetime.IsEternal)
return createTask(myBindLifetime);

var intersectedDef = Lifetime.DefineIntersection(requestLifetime, myBindLifetime);
var task = createTask(intersectedDef.Lifetime);
task.Result.Advise(intersectedDef.Lifetime, result =>
{
if (result.Status != RdTaskStatus.Success || !result.Result.IsBindable())
{
intersectedDef.AllowTerminationUnderExecution = true;
intersectedDef.Terminate();
}
});

return task;
}

public static RdCall<TReq, TRes> Read(SerializationCtx ctx, UnsafeReader reader, CtxReadDelegate<TReq> readRequest, CtxWriteDelegate<TReq> writeRequest, CtxReadDelegate<TRes> readResponse, CtxWriteDelegate<TRes> writeResponse)
{
return new RdCall<TReq, TRes>(readRequest, writeRequest, readResponse, writeResponse).WithId(reader.ReadRdId());
Expand Down
2 changes: 2 additions & 0 deletions rd-net/RdFramework/Tasks/WiredRdTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ internal class CallSite : WiredRdTask<TReq, TRes>
{
private readonly Lifetime myOuterLifetime;

public Lifetime Lifetime => myOuterLifetime;

public CallSite(Lifetime outerLifetime, RdCall<TReq, TRes> call, RdId rdId, IScheduler wireScheduler) : base(call, rdId, wireScheduler)
{
myOuterLifetime = outerLifetime;
Expand Down

0 comments on commit 5d6c9de

Please sign in to comment.