private async Task <TResponse> PerformOperationAsync <TResponse>( IGrpcRequest request, Func <ServiceOperationContext, Task <TResponse> > taskFunc, CancellationToken token, [CallerMemberName] string operation = null) where TResponse : IGrpcResponse, new() { var stopwatch = StopwatchSlim.Start(); DateTime startTime = DateTime.UtcNow; var cacheContext = new OperationContext(new Context(new Guid(request.Header.TraceId), Logger), token); var sessionId = request.Header.SessionId; if (!_cacheSessionHandler.TryGetSession(sessionId, out var session)) { return(failure($"Could not find session for session ID {sessionId}")); } await Task.Yield(); try { var serviceOperationContext = new ServiceOperationContext(session, cacheContext, startTime); var result = await taskFunc(serviceOperationContext); if (result.Header == null) { result.Header = ResponseHeader.Success(startTime); } Logger.Info($"GRPC server operation '{operation}' succeeded by {stopwatch.Elapsed.TotalMilliseconds}ms."); return(result); } catch (TaskCanceledException) { Logger.Info($"GRPC server operation '{operation}' is canceled by {stopwatch.Elapsed.TotalMilliseconds}ms."); return(failure("The operation was canceled.")); } catch (ResultPropagationException e) { Logger.Error(e, $"GRPC server operation '{operation}' failed by {stopwatch.Elapsed.TotalMilliseconds}ms. Error: {e}"); return(new TResponse { Header = ResponseHeader.Failure(startTime, e.Result.ErrorMessage, e.Result.Diagnostics) }); } catch (Exception e) { Logger.Error(e, $"GRPC server operation '{operation}' failed by {stopwatch.Elapsed.TotalMilliseconds}ms. Error: {e}"); return(failure(e.ToString())); } TResponse failure(string errorMessage) => new TResponse { Header = ResponseHeader.Failure(startTime, errorMessage) }; }
private async Task <TResponse> PerformOperationAsync <TResponse>( IGrpcRequest request, Func <ServiceOperationContext, Task <TResponse> > taskFunc, CancellationToken token, [CallerMemberName] string operation = null !) where TResponse : IGrpcResponse, new() { var sw = StopwatchSlim.Start(); DateTime startTime = DateTime.UtcNow; using var shutdownTracker = TrackShutdown(new OperationContext(new Context(new Guid(request.Header.TraceId), Logger), token), token); var tracingContext = shutdownTracker.Context; var sessionId = request.Header.SessionId; if (!_cacheSessionHandler.TryGetSession(sessionId, out var session)) { return(failure($"Could not find session for session ID {sessionId}")); } await Task.Yield(); try { var serviceOperationContext = new ServiceOperationContext(session, tracingContext, startTime); TraceGrpcOperationStarted(tracingContext, enabled: TraceGrpcOperations, operation, sessionId); var result = await taskFunc(serviceOperationContext); if (result.Header == null) { result.Header = ResponseHeader.Success(startTime); } TraceGrpcOperationFinished(tracingContext, enabled: TraceGrpcOperations, operation, sw.Elapsed, sessionId); return(result); } catch (TaskCanceledException e) { var message = GetLogMessage(e, operation, sessionId); Tracer.OperationFinished(tracingContext, FromException(e), sw.Elapsed, message, operation); return(failure(message)); } catch (ResultPropagationException e) { var message = GetLogMessage(e, operation, sessionId); Tracer.OperationFinished(tracingContext, FromException(e), sw.Elapsed, message, operation); return(new TResponse { Header = ResponseHeader.Failure(startTime, e.Result.ErrorMessage, e.Result.Diagnostics) }); } catch (Exception e) { var message = GetLogMessage(e, operation, sessionId); Tracer.OperationFinished(tracingContext, FromException(e), sw.Elapsed, message, operation); return(failure(e.ToString())); } TResponse failure(string errorMessage) => new TResponse { Header = ResponseHeader.Failure(startTime, errorMessage) }; }