コード例 #1
0
        public async Task RouteNotification(IHandlerDescriptor descriptor, Notification notification)
        {
            using (_logger.TimeDebug("Routing Notification {Method}", notification.Method))
            {
                using (_logger.BeginScope(new[] {
                    new KeyValuePair <string, string>("Method", notification.Method),
                    new KeyValuePair <string, string>("Params", notification.Params?.ToString())
                }))
                    using (var scope = _serviceScopeFactory.CreateScope())
                    {
                        var context = scope.ServiceProvider.GetRequiredService <IRequestContext>();
                        context.Descriptor = descriptor;
                        var mediator = scope.ServiceProvider.GetRequiredService <IMediator>();

                        try
                        {
                            if (descriptor.Params is null)
                            {
                                await MediatRHandlers.HandleNotification(mediator, descriptor, EmptyRequest.Instance, CancellationToken.None);
                            }
                            else
                            {
                                _logger.LogDebug("Converting params for Notification {Method} to {Type}", notification.Method, descriptor.Params.FullName);
                                var @params = (notification.Params ?? new JObject()).ToObject(descriptor.Params, _serializer.JsonSerializer);

                                await MediatRHandlers.HandleNotification(mediator, descriptor, @params ?? EmptyRequest.Instance, CancellationToken.None);
                            }
                        }
                        catch (Exception e)
                        {
                            _logger.LogCritical(Events.UnhandledRequest, e, "Failed to handle request {Method}", notification.Method);
                        }
                    }
            }
        }
コード例 #2
0
        public async Task <ErrorResponse> RouteRequest(IHandlerDescriptor descriptor, Request request)
        {
            using (_logger.TimeDebug("Routing Request ({Id}) {Method}", request.Id, request.Method))
            {
                using (_logger.BeginScope(new[] {
                    new KeyValuePair <string, string>("Id", request.Id?.ToString()),
                    new KeyValuePair <string, string>("Method", request.Method),
                    new KeyValuePair <string, string>("Params", request.Params?.ToString())
                }))
                    using (var scope = _serviceScopeFactory.CreateScope())
                    {
                        var context = scope.ServiceProvider.GetRequiredService <IRequestContext>();
                        context.Descriptor = descriptor;
                        var mediator = scope.ServiceProvider.GetRequiredService <IMediator>();

                        var id  = GetId(request.Id);
                        var cts = new CancellationTokenSource();
                        _requests.TryAdd(id, cts);

                        // TODO: Try / catch for Internal Error
                        try
                        {
                            if (descriptor is null)
                            {
                                _logger.LogDebug("descriptor not found for Request ({Id}) {Method}", request.Id, request.Method);
                                return(new MethodNotFound(request.Id, request.Method));
                            }

                            object @params;
                            try
                            {
                                _logger.LogDebug("Converting params for Request ({Id}) {Method} to {Type}", request.Id, request.Method, descriptor.Params.FullName);
                                @params = request.Params?.ToObject(descriptor.Params, _serializer.JsonSerializer);
                            }
                            catch (Exception cannotDeserializeRequestParams)
                            {
                                _logger.LogError(new EventId(-32602), cannotDeserializeRequestParams, "Failed to deserialise request parameters.");
                                return(new InvalidParams(request.Id));
                            }

                            var   result = MediatRHandlers.HandleRequest(mediator, descriptor, @params ?? EmptyRequest.Instance, cts.Token);
                            await result;

                            _logger.LogDebug("Result was {Type}", result.GetType().FullName);

                            object responseValue = null;
                            if (result.GetType().GetTypeInfo().IsGenericType)
                            {
                                var property = typeof(Task <>)
                                               .MakeGenericType(result.GetType().GetTypeInfo().GetGenericArguments()[0]).GetTypeInfo()
                                               .GetProperty(nameof(Task <object> .Result), BindingFlags.Public | BindingFlags.Instance);

                                responseValue = property.GetValue(result);
                                if (responseValue?.GetType() == typeof(Unit))
                                {
                                    responseValue = null;
                                }
                                _logger.LogDebug("Response value was {Type}", responseValue?.GetType().FullName);
                            }

                            return(new JsonRpc.Client.Response(request.Id, responseValue));
                        }
                        catch (TaskCanceledException e)
                        {
                            _logger.LogDebug("Request {Id} was cancelled", id);
                            return(new RequestCancelled());
                        }
                        catch (Exception e)
                        {
                            _logger.LogCritical(Events.UnhandledRequest, e, "Failed to handle notification {Method}", request.Method);
                            return(new InternalError(id, e.ToString()));
                        }
                        finally
                        {
                            _requests.TryRemove(id, out var _);
                        }
                    }
            }
        }