diff --git a/dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayTypes.cs b/dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayTypes.cs index f921ed1..ddeb7b4 100644 --- a/dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayTypes.cs +++ b/dotnet/src/ZB.MOM.NatsNet.Server/Gateway/GatewayTypes.cs @@ -15,6 +15,7 @@ using System.Text; using System.Threading; +using System.Linq; using ZB.MOM.NatsNet.Server.Internal; using ZB.MOM.NatsNet.Server.Internal.DataStructures; @@ -256,6 +257,11 @@ internal sealed class SrvGateway public void ReleaseReadLock() => _lock.ExitReadLock(); public void AcquireWriteLock() => _lock.EnterWriteLock(); public void ReleaseWriteLock() => _lock.ExitWriteLock(); + + internal void OrderOutboundConnectionsLocked() + { + Outo = [.. Out.Values.OrderBy(c => c.GetRttValue()).ThenBy(c => c.Cid)]; + } } /// diff --git a/dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConnectionsAndGossip.cs b/dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConnectionsAndGossip.cs index cd5d823..e01af38 100644 --- a/dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConnectionsAndGossip.cs +++ b/dotnet/src/ZB.MOM.NatsNet.Server/NatsServer.Gateways.ConnectionsAndGossip.cs @@ -144,6 +144,133 @@ public sealed partial class NatsServer } } + internal void AddGatewayURL(string gatewayName, string gatewayUrl) + { + if (string.IsNullOrWhiteSpace(gatewayUrl)) + return; + + _gateway.AcquireWriteLock(); + try + { + _gateway.Urls.AddUrl(gatewayUrl); + if (_gateway.Remotes.TryGetValue(gatewayName, out var cfg) && Uri.TryCreate(gatewayUrl, UriKind.Absolute, out var url)) + cfg.AddUrls([url]); + } + finally + { + _gateway.ReleaseWriteLock(); + } + } + + internal void RemoveGatewayURL(string gatewayName, string gatewayUrl) + { + if (string.IsNullOrWhiteSpace(gatewayUrl)) + return; + + _gateway.AcquireWriteLock(); + try + { + _gateway.Urls.RemoveUrl(gatewayUrl); + + if (_gateway.Remotes.TryGetValue(gatewayName, out var cfg)) + { + cfg.AcquireWriteLock(); + try + { + cfg.Urls.Remove(gatewayUrl); + cfg.VarzUpdateUrls = true; + } + finally + { + cfg.ReleaseWriteLock(); + } + } + } + finally + { + _gateway.ReleaseWriteLock(); + } + } + + internal void SendAsyncGatewayInfo() + { + byte[] infoProto; + _gateway.AcquireReadLock(); + try + { + infoProto = _gateway.InfoJson is { Length: > 0 } proto + ? [.. proto] + : _gateway.GenerateInfoJSON(); + } + finally + { + _gateway.ReleaseReadLock(); + } + + _mu.EnterReadLock(); + try + { + foreach (var route in _routes.Values.SelectMany(v => v)) + route.EnqueueProto(infoProto); + + foreach (var inbound in _gateway.In.Values) + inbound.EnqueueProto(infoProto); + } + finally + { + _mu.ExitReadLock(); + } + } + + internal string GetGatewayURL() + { + _gateway.AcquireReadLock(); + try { return _gateway.Url; } + finally { _gateway.ReleaseReadLock(); } + } + + internal string GetGatewayName() + { + _gateway.AcquireReadLock(); + try { return _gateway.Name; } + finally { _gateway.ReleaseReadLock(); } + } + + internal void RegisterInboundGatewayConnection(ClientConnection connection) + { + _gateway.AcquireWriteLock(); + try { _gateway.In[connection.Cid] = connection; } + finally { _gateway.ReleaseWriteLock(); } + } + + internal void RegisterOutboundGatewayConnection(string gatewayName, ClientConnection connection) + { + _gateway.AcquireWriteLock(); + try + { + _gateway.Out[gatewayName] = connection; + _gateway.OrderOutboundConnectionsLocked(); + } + finally + { + _gateway.ReleaseWriteLock(); + } + } + + internal ClientConnection? GetOutboundGatewayConnection(string gatewayName) + { + _gateway.AcquireReadLock(); + try { return _gateway.Out.GetValueOrDefault(gatewayName); } + finally { _gateway.ReleaseReadLock(); } + } + + internal IReadOnlyList GetOutboundGatewayConnections() + { + _gateway.AcquireReadLock(); + try { return [.. _gateway.Outo]; } + finally { _gateway.ReleaseReadLock(); } + } + public int NumOutboundGateways() => NumOutboundGatewaysInternal(); internal int NumOutboundGatewaysInternal() diff --git a/porting.db b/porting.db index 5bf2033..07133d6 100644 Binary files a/porting.db and b/porting.db differ