using StellaOps.Plugin.Abstractions.Capabilities;
using StellaOps.Plugin.Abstractions.Context;
using StellaOps.Router.Common.Abstractions;
namespace StellaOps.Router.Plugin.Unified;
///
/// Adapts ITransportServer to ITransportServerInstance.
///
internal sealed class TransportServerAdapter : ITransportServerInstance
{
private readonly ITransportServer _inner;
private readonly IPluginLogger _logger;
private bool _isRunning;
private bool _disposed;
///
/// Gets the server identifier.
///
public string ServerId { get; }
///
public bool IsRunning => _isRunning;
///
public TransportEndpoint LocalEndpoint { get; }
///
public int ActiveConnections
{
get
{
// Try to get connection count from the inner server if it exposes this
// Otherwise return 0 as we cannot determine this
var serverType = _inner.GetType();
var countProperty = serverType.GetProperty("ConnectionCount");
if (countProperty != null)
{
return (int)(countProperty.GetValue(_inner) ?? 0);
}
return 0;
}
}
///
/// Creates a new server adapter.
///
public TransportServerAdapter(
ITransportServer inner,
string serverId,
TransportEndpoint endpoint,
IPluginLogger logger)
{
_inner = inner ?? throw new ArgumentNullException(nameof(inner));
ServerId = serverId;
LocalEndpoint = endpoint;
_logger = logger;
}
///
public async Task StartAsync(CancellationToken ct)
{
ObjectDisposedException.ThrowIf(_disposed, this);
if (_isRunning)
{
return;
}
await _inner.StartAsync(ct);
_isRunning = true;
_logger.Info("Transport server {ServerId} started on {Host}:{Port}",
ServerId, LocalEndpoint.Host, LocalEndpoint.Port);
}
///
public async Task StopAsync(CancellationToken ct)
{
if (!_isRunning)
{
return;
}
await _inner.StopAsync(ct);
_isRunning = false;
_logger.Info("Transport server {ServerId} stopped", ServerId);
}
///
public async ValueTask DisposeAsync()
{
if (_disposed)
{
return;
}
_disposed = true;
if (_isRunning)
{
await StopAsync(CancellationToken.None);
}
if (_inner is IAsyncDisposable asyncDisposable)
{
await asyncDisposable.DisposeAsync();
}
else if (_inner is IDisposable disposable)
{
disposable.Dispose();
}
}
}