private Task WaitForCompletionAsync(RequestInvocationHandle handle, CancellationToken cancellationToken)
        {
            var asyncResetEvent = new AsyncManualResetEvent(initialState: false);

            handle.OnComplete += (r) =>
            {
                asyncResetEvent.Set();
            };
            return(asyncResetEvent.WaitAsync(cancellationToken));
        }
Example #2
0
        public override RequestInvocationHandle InvokeRequest(IRequestDescriptor <IHandlerDescriptor?> descriptor, Request request)
        {
            if (descriptor.Default is null)
            {
                throw new ArgumentNullException(nameof(descriptor.Default));
            }

            var handle = new RequestInvocationHandle(request);
            var type   = _requestProcessIdentifier.Identify(descriptor.Default);

            var schedulerDelegate = BuildRequestDelegate(descriptor, request, handle);

            _requestScheduler.Schedule(type, $"{request.Method}:{request.Id}", schedulerDelegate);

            return(handle);
        }
Example #3
0
        private ProcessSchedulerDelegate BuildRequestDelegate(IRequestDescriptor <IHandlerDescriptor?> descriptors, Request request, RequestInvocationHandle handle)
        {
            return(async(cancellationToken) =>
            {
                try
                {
                    var result = await InvokeRequestAsync(cancellationToken).ConfigureAwait(false);

                    _outputHandler.Send(result.Value);
                }
                finally
                {
                    handle.Dispose();
                }
            });

            async Task <ErrorResponse> InvokeRequestAsync(CancellationToken cancellationToken)
            {
                using var timeoutCts  = new CancellationTokenSource(_requestTimeout);
                using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(handle.CancellationTokenSource.Token, timeoutCts.Token, cancellationToken);

                using var timer = _logger.TimeDebug("Processing request {Method}:{Id}", request.Method, request.Id);
                try
                {
                    var result = await _requestRouter.RouteRequest(descriptors, request, combinedCts.Token).ConfigureAwait(false);

                    return(result);
                }
                catch (OperationCanceledException)
                {
                    if (timeoutCts.IsCancellationRequested)
                    {
                        _logger.LogTrace("Request {Method}:{Id} was cancelled, due to timeout", request.Method, request.Id);
                        return(new RequestCancelled(request.Id, request.Method));
                    }

                    _logger.LogTrace("Request {Method}:{Id} was cancelled", request.Method, request.Id);
                    return(new RequestCancelled(request.Id, request.Method));
                }
                catch (RpcErrorException e)
                {
                    _logger.LogCritical(Events.UnhandledRequest, e, "Failed to handle request {Method}:{Id}", request.Method, request.Id);
                    return(new RpcError(
                               request.Id,
                               request.Method,
                               new ErrorMessage(e.Code, e.Message, e.Error)));
                }
                catch (Exception e)
                {
                    _logger.LogCritical(Events.UnhandledRequest, e, "Failed to handle request {Method}:{Id}. Unhandled exception", request.Method, request.Id);
                    return(new InternalError(request.Id, request.Method, e.ToString()));
                }
            }
        }