< Summary

Information
Class: NostrSure.Infrastructure.Client.Implementation.ConnectionManager
Assembly: NostrSure.Infrastructure
File(s): /home/runner/work/NostrSure/NostrSure/NostrSure.Infrastructure/Client/Implementation/ConnectionManager.cs
Line coverage
83%
Covered lines: 49
Uncovered lines: 10
Coverable lines: 59
Total lines: 97
Line coverage: 83%
Branch coverage
50%
Covered branches: 13
Total branches: 26
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%66100%
get_State()100%11100%
ConnectAsync()33.33%7668.75%
CloseAsync()50%121075%
Dispose()75%44100%

File(s)

/home/runner/work/NostrSure/NostrSure/NostrSure.Infrastructure/Client/Implementation/ConnectionManager.cs

#LineLine coverage
 1using System.Net.WebSockets;
 2using Microsoft.Extensions.Logging;
 3using NostrSure.Infrastructure.Client.Abstractions;
 4
 5namespace NostrSure.Infrastructure.Client.Implementation;
 6
 7/// <summary>
 8/// Manages WebSocket connection lifecycle operations
 9/// </summary>
 10public sealed class ConnectionManager : IConnectionManager
 11{
 12    private readonly IClientWebSocket _webSocket;
 13    private readonly IConnectionStateManager _stateManager;
 14    private readonly IConnectionErrorHandler _errorHandler;
 15    private readonly CancellationTokenSource _cancellationTokenSource;
 16    private readonly ILogger<ConnectionManager>? _logger;
 17    private bool _disposed;
 18
 419    public ConnectionManager(
 420        IClientWebSocket webSocket,
 421        IConnectionStateManager stateManager,
 422        IConnectionErrorHandler errorHandler,
 423        ILogger<ConnectionManager>? logger = null)
 424    {
 425        _webSocket = webSocket ?? throw new ArgumentNullException(nameof(webSocket));
 426        _stateManager = stateManager ?? throw new ArgumentNullException(nameof(stateManager));
 427        _errorHandler = errorHandler ?? throw new ArgumentNullException(nameof(errorHandler));
 428        _cancellationTokenSource = new CancellationTokenSource();
 429        _logger = logger;
 430    }
 31
 232    public WebSocketState State => _webSocket.State;
 33
 34    public event EventHandler? Disconnected;
 35
 36    public async Task ConnectAsync(Uri uri, CancellationToken cancellationToken = default)
 237    {
 38        try
 239        {
 240            _logger?.LogDebug("Attempting to connect to {Uri}", uri);
 41
 242            var combinedToken = CancellationTokenSource
 243                .CreateLinkedTokenSource(cancellationToken, _cancellationTokenSource.Token)
 244                .Token;
 45
 246            await _webSocket.ConnectAsync(uri, combinedToken);
 247            _stateManager.UpdateState(WebSocketState.Open);
 48
 249            _logger?.LogInformation("Successfully connected to {Uri}", uri);
 250        }
 051        catch (Exception ex)
 052        {
 053            _logger?.LogError(ex, "Failed to connect to {Uri}", uri);
 054            await _errorHandler.HandleErrorAsync(ex, nameof(ConnectAsync));
 055            throw;
 56        }
 257    }
 58
 59    public async Task CloseAsync(WebSocketCloseStatus closeStatus = WebSocketCloseStatus.NormalClosure,
 60                                string? statusDescription = null,
 61                                CancellationToken cancellationToken = default)
 162    {
 63        try
 164        {
 165            _logger?.LogDebug("Closing WebSocket connection with status {CloseStatus}", closeStatus);
 66
 167            if (_webSocket.State == WebSocketState.Open)
 168            {
 169                await _webSocket.CloseAsync(closeStatus, statusDescription, cancellationToken);
 170                _stateManager.UpdateState(_webSocket.State);
 171                _logger?.LogInformation("WebSocket connection closed successfully");
 172            }
 173        }
 074        catch (Exception ex)
 075        {
 076            _logger?.LogError(ex, "Error occurred while closing WebSocket connection");
 077            await _errorHandler.HandleErrorAsync(ex, nameof(CloseAsync));
 078        }
 79        finally
 180        {
 181            _cancellationTokenSource.Cancel();
 182            Disconnected?.Invoke(this, EventArgs.Empty);
 183        }
 184    }
 85
 86    public void Dispose()
 187    {
 188        if (!_disposed)
 189        {
 190            _logger?.LogDebug("Disposing ConnectionManager");
 191            _cancellationTokenSource.Cancel();
 192            _cancellationTokenSource.Dispose();
 193            _webSocket.Dispose();
 194            _disposed = true;
 195        }
 196    }
 97}