feat: add structured logging, Shouldly assertions, CPM, and project documentation
- Add Microsoft.Extensions.Logging + Serilog to NatsServer and NatsClient - Convert all test assertions from xUnit Assert to Shouldly - Add NSubstitute package for future mocking needs - Introduce Central Package Management via Directory.Packages.props - Add documentation_rules.md with style guide, generation/update rules, component map - Generate 10 documentation files across 5 component folders (GettingStarted, Protocol, Subscriptions, Server, Configuration/Operations) - Update CLAUDE.md with logging, testing, porting, agent model, CPM, and documentation guidance
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using NATS.Server.Protocol;
|
||||
using NATS.Server.Subscriptions;
|
||||
|
||||
@@ -12,14 +13,18 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
private readonly ConcurrentDictionary<ulong, NatsClient> _clients = new();
|
||||
private readonly SubList _subList = new();
|
||||
private readonly ServerInfo _serverInfo;
|
||||
private readonly ILogger<NatsServer> _logger;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private Socket? _listener;
|
||||
private ulong _nextClientId;
|
||||
|
||||
public SubList SubList => _subList;
|
||||
|
||||
public NatsServer(NatsOptions options)
|
||||
public NatsServer(NatsOptions options, ILoggerFactory loggerFactory)
|
||||
{
|
||||
_options = options;
|
||||
_loggerFactory = loggerFactory;
|
||||
_logger = loggerFactory.CreateLogger<NatsServer>();
|
||||
_serverInfo = new ServerInfo
|
||||
{
|
||||
ServerId = Guid.NewGuid().ToString("N")[..20].ToUpperInvariant(),
|
||||
@@ -40,6 +45,8 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
_options.Port));
|
||||
_listener.Listen(128);
|
||||
|
||||
_logger.LogInformation("Listening on {Host}:{Port}", _options.Host, _options.Port);
|
||||
|
||||
try
|
||||
{
|
||||
while (!ct.IsCancellationRequested)
|
||||
@@ -47,7 +54,10 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
var socket = await _listener.AcceptAsync(ct);
|
||||
var clientId = Interlocked.Increment(ref _nextClientId);
|
||||
|
||||
var client = new NatsClient(clientId, socket, _options, _serverInfo);
|
||||
_logger.LogDebug("Client {ClientId} connected from {RemoteEndpoint}", clientId, socket.RemoteEndPoint);
|
||||
|
||||
var clientLogger = _loggerFactory.CreateLogger($"NATS.Server.NatsClient[{clientId}]");
|
||||
var client = new NatsClient(clientId, socket, _options, _serverInfo, clientLogger);
|
||||
client.Router = this;
|
||||
_clients[clientId] = client;
|
||||
|
||||
@@ -69,6 +79,7 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
}
|
||||
finally
|
||||
{
|
||||
_logger.LogDebug("Client {ClientId} disconnected", client.Id);
|
||||
RemoveClient(client);
|
||||
}
|
||||
}
|
||||
@@ -127,6 +138,7 @@ public sealed class NatsServer : IMessageRouter, ISubListAccess, IDisposable
|
||||
public void RemoveClient(NatsClient client)
|
||||
{
|
||||
_clients.TryRemove(client.Id, out _);
|
||||
_logger.LogDebug("Removed client {ClientId}", client.Id);
|
||||
client.RemoveAllSubscriptions(_subList);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user