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); } } } }
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 _); } } } }