feat: add route pool size negotiation (Gap 13.3)

Add NegotiatePoolSize static method and NegotiatedPoolSize property to
RouteConnection, and ConfiguredPoolSize / GetEffectivePoolSize to
RouteManager. Includes 14 tests covering negotiation semantics, backward
compatibility (zero means no pooling), default state, and deterministic
pool index computation.
This commit is contained in:
Joseph Doherty
2026-02-25 12:05:57 -05:00
parent 071717dcbf
commit b9c83d6b3b
2 changed files with 240 additions and 0 deletions

View File

@@ -22,6 +22,36 @@ public sealed class RouteConnection(Socket socket) : IAsyncDisposable
/// for a given account. See <see cref="RouteManager.ComputeRoutePoolIdx"/>.
/// </summary>
public int PoolIndex { get; set; }
/// <summary>
/// The pool size agreed upon during handshake negotiation with the remote peer.
/// Defaults to 0 (no pooling / pre-negotiation state). Set after handshake completes.
/// Go reference: server/route.go negotiateRoutePool.
/// </summary>
public int NegotiatedPoolSize { get; private set; }
/// <summary>
/// Negotiates the effective route pool size between local and remote peers.
/// Returns <c>Math.Min(localPoolSize, remotePoolSize)</c>, but returns 0 if
/// either side is 0 for backward compatibility with peers that do not support pooling.
/// Go reference: server/route.go negotiateRoutePool.
/// </summary>
public static int NegotiatePoolSize(int localPoolSize, int remotePoolSize)
{
if (localPoolSize == 0 || remotePoolSize == 0)
return 0;
return Math.Min(localPoolSize, remotePoolSize);
}
/// <summary>
/// Applies the result of pool size negotiation to this connection.
/// </summary>
internal void SetNegotiatedPoolSize(int negotiatedPoolSize)
{
NegotiatedPoolSize = negotiatedPoolSize;
}
public Func<RemoteSubscription, Task>? RemoteSubscriptionReceived { get; set; }
public Func<RouteMessage, Task>? RoutedMessageReceived { get; set; }