private static RdTask <T> FromResult(RdTaskResult <T> result) { var res = new RdTask <T>(); res.ResultInternal.Value = result; return(res); }
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 static void SetAndLogErrors <TReq, TRes>(this RdEndpoint <TReq, TRes> endpoint, Action <TReq, RdTask <TRes> > handler, ILog logger) { endpoint.Set((lifetime, req) => { try { var task = new RdTask <TRes>(); handler(req, task); return(task); } catch (Exception ex) { logger.Error(ex); throw; } }); }
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)); } }); } }
public static RdTask <Unit> ToRdTask(this Task task) { var res = new RdTask <Unit>(); task.ContinueWith(t => { if (t.IsOperationCanceled()) { res.SetCancelled(); } else if (t.IsFaulted) { res.Set(t.Exception?.Flatten().GetBaseException()); } else { res.Set(Unit.Instance); } }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current); return(res); }
public static RdTask <T> ToRdTask <T>(this Task <T> task, CancellationToken token, TaskContinuationOptions continuationOptions = TaskContinuationOptions.None, TaskScheduler scheduler = null) { var rdTask = new RdTask <T>(); task.ContinueWith((tsk, rdTaskObject) => { var rdTask1 = (RdTask <T>)rdTaskObject; if (tsk.IsCanceled) { rdTask1.SetCancelled(); } else if (tsk.IsFaulted) { rdTask1.Set(tsk.Exception?.Flatten().GetBaseException()); } else { rdTask1.Set(tsk.Result); } }, rdTask, token, continuationOptions, scheduler ?? TaskScheduler.Current); return(rdTask); }
[PublicAPI] public static void Set <TReq, TRes>(this IRdEndpoint <TReq, TRes> endpoint, Func <TReq, TRes> handler, IScheduler cancellationScheduler = null, IScheduler handlerScheduler = null) { endpoint.Set((_, req) => RdTask <TRes> .Successful(handler(req)), cancellationScheduler, handlerScheduler); }
public override void OnWireReceived(UnsafeReader reader) { var taskId = RdId.Read(reader); var value = ReadRequestDelegate(SerializationContext, reader); if (LogReceived.IsTraceEnabled()) { LogReceived.Trace("endpoint `{0}`::({1}), taskId={2}, request = {3}", Location, RdId, taskId, value.PrintToString()); } var taskLifetimeDef = myBindLifetime.CreateNested(); //subscribe for lifetime cancellation new WiredLifetime(taskLifetimeDef, taskId, this, Wire); RdTask <TRes> rdTask; using (UsingDebugInfo()) //now supports only sync handlers { try { rdTask = Handler(taskLifetimeDef.Lifetime, value); } catch (Exception e) { rdTask = RdTask <TRes> .Faulted(e); } } rdTask.Result.Advise(taskLifetimeDef.Lifetime, result => { if (LogSend.IsTraceEnabled()) { LogSend.Trace("endpoint `{0}`::({1}), taskId={2}, response = {3}", Location, RdId, taskId, result.PrintToString()); } RdTaskResult <TRes> validatedResult; try { if (result.Status == RdTaskStatus.Success) { AssertNullability(result.Result); } validatedResult = result; } catch (Exception e) { LogSend.Error(e); validatedResult = RdTaskResult <TRes> .Faulted(e); } Wire.Send(taskId, writer => { RdTaskResult <TRes> .Write(WriteResponseDelegate, SerializationContext, writer, validatedResult); }); taskLifetimeDef.Terminate(); //need to terminate to unsubscribe lifetime listener - not for bindable entries }); }
public void SetHandler([NotNull] Func <TReq, TRes> handler) { Assertion.Assert(myHandler == null, "Handler already initialized"); myHandler = (lt, req) => RdTask <TRes> .Successful(handler(req)); }
[PublicAPI] public static void Set <TReq, TRes>(this IRdEndpoint <TReq, TRes> endpoint, Func <TReq, TRes> handler) { endpoint.Set((_, req) => RdTask <TRes> .Successful(handler(req))); }