private IRdTask <TRes> StartInternal(Lifetime requestLifetime, TReq request, [NotNull] IScheduler scheduler) { AssertBound(); if (!Async) { AssertThreading(); } AssertNullability(request); var taskId = Proto.Identities.Next(RdId.Nil); var def = Lifetime.DefineIntersection(requestLifetime, myBindLifetime); var task = new WiredRdTask <TReq, TRes>(def, this, taskId, scheduler); Wire.Send(RdId, (writer) => { if (LogSend.IsTraceEnabled()) { LogSend.Trace("call `{0}`::({1}) send request '{2}' : {3}", Location, RdId, taskId, request.PrintToString()); } taskId.Write(writer); WriteRequestDelegate(SerializationContext, writer, request); }); return(task); }
private IRdTask <TRes> StartInternal(Lifetime requestLifetime, TReq request, [NotNull] IScheduler scheduler) { AssertBound(); if (!Async) { AssertThreading(); } AssertNullability(request); var taskId = Proto.Identities.Next(RdId.Nil); var task = new WiredRdTask <TReq, TRes>(this, taskId, scheduler, false); //no need for cancellationLifetime on call site var _ = task.Subscribe(Lifetime.Intersect(requestLifetime, myBindLifetime)); Wire.Send(RdId, (writer) => { SendTrace?.Log($"{task} :: send request: {request.PrintToString()}"); taskId.Write(writer); WriteRequestDelegate(SerializationContext, writer, request); }); return(task); }
public override void OnWireReceived(UnsafeReader reader) //endpoint's side { var taskId = RdId.Read(reader); var wiredTask = new WiredRdTask <TReq, TRes> .Endpoint(myBindLifetime, this, taskId, myCancellationScheduler ?? SynchronousScheduler.Instance); //subscribe for lifetime cancellation var externalCancellation = wiredTask.Lifetime; using (UsingDebugInfo()) //now supports only sync handlers { RdTask <TRes> rdTask; try { var value = ReadRequestDelegate(SerializationContext, reader); ReceiveTrace?.Log($"{wiredTask} :: received request: {value.PrintToString()}"); var handler = Handler; if (handler == null) { var message = $"Handler is not set for {wiredTask} :: received request: {value.PrintToString()}"; ourLogReceived.Error(message); rdTask = RdTask <TRes> .Faulted(new Exception(message)); } else { try { rdTask = handler(externalCancellation, value); } catch (Exception ex) { rdTask = RdTask <TRes> .Faulted(ex); } } } catch (Exception e) { rdTask = RdTask <TRes> .Faulted(new Exception($"Unexpected exception in {wiredTask}", e)); } rdTask.Result.Advise(Lifetime.Eternal, result => { try { if (result.Status == RdTaskStatus.Success) { AssertNullability(result.Result); } wiredTask.ResultInternal.SetIfEmpty(result); } catch (Exception ee) { ourLogSend.Error($"Problem when responding to `{wiredTask}`", ee); wiredTask.Set(new RdFault(ee)); } }); } }
public override void OnWireReceived(UnsafeReader reader) //endpoint's side { var taskId = RdId.Read(reader); var wiredTask = new WiredRdTask <TReq, TRes>(this, taskId, myEndpointSchedulerForHandlerAndCancellation ?? WireScheduler, true); //subscribe for lifetime cancellation var externalCancellation = wiredTask.Subscribe(myBindLifetime); using (UsingDebugInfo()) //now supports only sync handlers { RdTask <TRes> rdTask; try { var value = ReadRequestDelegate(SerializationContext, reader); ReceiveTrace?.Log($"{wiredTask} :: received request: {value.PrintToString()}"); rdTask = Handler(externalCancellation, value); } catch (Exception e) { rdTask = RdTask <TRes> .Faulted(e); } rdTask.Result.Advise(Lifetime.Eternal, result => { try { if (result.Status == RdTaskStatus.Success) { AssertNullability(result.Result); } wiredTask.ResultInternal.SetIfEmpty(result); } catch (Exception ee) { ourLogSend.Error($"Problem when responding to `{wiredTask}`", ee); wiredTask.Set(new RdFault(ee)); } }); } }