| | | 1 | | // Copyright (c) ZeroC, Inc. |
| | | 2 | | |
| | | 3 | | using IceRpc.Transports; |
| | | 4 | | |
| | | 5 | | namespace IceRpc.Internal; |
| | | 6 | | |
| | | 7 | | /// <summary>Provides a log decorator for protocol connections.</summary> |
| | | 8 | | internal class MetricsProtocolConnectionDecorator : IProtocolConnection |
| | | 9 | | { |
| | | 10 | | private readonly bool _connectStarted; |
| | | 11 | | private readonly IProtocolConnection _decoratee; |
| | | 12 | | private bool _isConnected; |
| | | 13 | | private bool _isShutdown; |
| | | 14 | | private readonly Metrics _metrics; |
| | | 15 | | |
| | | 16 | | public async Task<(TransportConnectionInformation ConnectionInformation, Task ShutdownRequested)> ConnectAsync( |
| | | 17 | | CancellationToken cancellationToken) |
| | 278 | 18 | | { |
| | 278 | 19 | | if (!_connectStarted) |
| | 163 | 20 | | { |
| | 163 | 21 | | _metrics.ConnectStart(); |
| | 163 | 22 | | } |
| | | 23 | | try |
| | 278 | 24 | | { |
| | 278 | 25 | | (TransportConnectionInformation connectionInformation, Task shutdownRequested) = |
| | 278 | 26 | | await _decoratee.ConnectAsync(cancellationToken).ConfigureAwait(false); |
| | 226 | 27 | | _metrics.ConnectSuccess(); |
| | 226 | 28 | | _isConnected = true; |
| | 226 | 29 | | return (connectionInformation, shutdownRequested); |
| | | 30 | | } |
| | 52 | 31 | | catch |
| | 52 | 32 | | { |
| | 52 | 33 | | _metrics.ConnectionFailure(); |
| | 52 | 34 | | throw; |
| | | 35 | | } |
| | | 36 | | finally |
| | 278 | 37 | | { |
| | 278 | 38 | | _metrics.ConnectStop(); |
| | 278 | 39 | | } |
| | 226 | 40 | | } |
| | | 41 | | |
| | | 42 | | public async ValueTask DisposeAsync() |
| | 278 | 43 | | { |
| | 278 | 44 | | await _decoratee.DisposeAsync().ConfigureAwait(false); |
| | 278 | 45 | | if (_isConnected) |
| | 226 | 46 | | { |
| | 226 | 47 | | if (!_isShutdown) |
| | 146 | 48 | | { |
| | | 49 | | // shutdown failed or didn't call shutdown at all. |
| | 146 | 50 | | _metrics.ConnectionFailure(); |
| | 146 | 51 | | } |
| | 226 | 52 | | _metrics.ConnectionDisconnected(); |
| | 226 | 53 | | } |
| | 278 | 54 | | } |
| | | 55 | | |
| | | 56 | | public Task<IncomingResponse> InvokeAsync(OutgoingRequest request, CancellationToken cancellationToken) => |
| | 160 | 57 | | _decoratee.InvokeAsync(request, cancellationToken); |
| | | 58 | | |
| | | 59 | | public async Task ShutdownAsync(CancellationToken cancellationToken) |
| | 101 | 60 | | { |
| | 101 | 61 | | await _decoratee.ShutdownAsync(cancellationToken).ConfigureAwait(false); |
| | 80 | 62 | | _isShutdown = true; |
| | 80 | 63 | | } |
| | | 64 | | |
| | | 65 | | /// <summary>A protocol connection decorator to log connection metrics.</summary> |
| | | 66 | | /// <param name="decoratee">The protocol connection decoratee.</param> |
| | | 67 | | /// <param name="metrics">The metrics object used to log the metrics.</param> |
| | | 68 | | /// <param name="connectStarted">Whether or not the ConnectStart events has be already logged. For server connection |
| | | 69 | | /// the event is logged from a separate <see cref="Server.IConnector"/> decorator.</param> |
| | 278 | 70 | | internal MetricsProtocolConnectionDecorator( |
| | 278 | 71 | | IProtocolConnection decoratee, |
| | 278 | 72 | | Metrics metrics, |
| | 278 | 73 | | bool connectStarted) |
| | 278 | 74 | | { |
| | 278 | 75 | | _connectStarted = connectStarted; |
| | 278 | 76 | | _decoratee = decoratee; |
| | 278 | 77 | | _metrics = metrics; |
| | 278 | 78 | | } |
| | | 79 | | } |