Files
git.stella-ops.org/src/Router/StellaOps.Router.Plugin.Unified/TransportServerAdapter.cs
2026-02-01 21:37:40 +02:00

117 lines
2.8 KiB
C#

using StellaOps.Plugin.Abstractions.Capabilities;
using StellaOps.Plugin.Abstractions.Context;
using StellaOps.Router.Common.Abstractions;
namespace StellaOps.Router.Plugin.Unified;
/// <summary>
/// Adapts ITransportServer to ITransportServerInstance.
/// </summary>
internal sealed class TransportServerAdapter : ITransportServerInstance
{
private readonly ITransportServer _inner;
private readonly IPluginLogger _logger;
private bool _isRunning;
private bool _disposed;
/// <summary>
/// Gets the server identifier.
/// </summary>
public string ServerId { get; }
/// <inheritdoc />
public bool IsRunning => _isRunning;
/// <inheritdoc />
public TransportEndpoint LocalEndpoint { get; }
/// <inheritdoc />
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;
}
}
/// <summary>
/// Creates a new server adapter.
/// </summary>
public TransportServerAdapter(
ITransportServer inner,
string serverId,
TransportEndpoint endpoint,
IPluginLogger logger)
{
_inner = inner ?? throw new ArgumentNullException(nameof(inner));
ServerId = serverId;
LocalEndpoint = endpoint;
_logger = logger;
}
/// <inheritdoc />
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);
}
/// <inheritdoc />
public async Task StopAsync(CancellationToken ct)
{
if (!_isRunning)
{
return;
}
await _inner.StopAsync(ct);
_isRunning = false;
_logger.Info("Transport server {ServerId} stopped", ServerId);
}
/// <inheritdoc />
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();
}
}
}