From 642ad1d9e4bb4c0872d6d12c9616e050c7fe61bd Mon Sep 17 00:00:00 2001 From: LD-Reborn Date: Tue, 14 Jul 2026 23:05:32 +0200 Subject: [PATCH] fix(Routing): adds global load balancing incrementer --- src/ReverseLlama.Server/TunnelHub.cs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/ReverseLlama.Server/TunnelHub.cs b/src/ReverseLlama.Server/TunnelHub.cs index dd5e909..60bbcef 100644 --- a/src/ReverseLlama.Server/TunnelHub.cs +++ b/src/ReverseLlama.Server/TunnelHub.cs @@ -1,5 +1,6 @@ using System.Collections.Concurrent; using System.Net.WebSockets; +using System.Threading; using ReverseLlama.Protocol; namespace ReverseLlama.Server; @@ -9,6 +10,7 @@ internal sealed class TunnelHub private readonly ConcurrentDictionary _connections = new(StringComparer.OrdinalIgnoreCase); private readonly ILogger _logger; private readonly ILoggerFactory _loggerFactory; + private long _roundRobinCounter; public TunnelHub(ILogger logger, ILoggerFactory loggerFactory) { @@ -40,17 +42,23 @@ internal sealed class TunnelHub var withModel = allOpen.Where(connection => connection.HasModel(model)).ToList(); if (withModel.Count > 0) { - return withModel - .OrderBy(connection => connection.PendingRequestCount) - .ThenBy(connection => connection.ClientId, StringComparer.OrdinalIgnoreCase) - .First(); + return PickBest(withModel); } } - return allOpen - .OrderBy(connection => connection.PendingRequestCount) - .ThenBy(connection => connection.ClientId, StringComparer.OrdinalIgnoreCase) - .First(); + return PickBest(allOpen); + } + + private TunnelConnection PickBest(List candidates) + { + var tick = (int)(Interlocked.Increment(ref _roundRobinCounter) & 0x7FFFFFFF); + + return candidates + .Select((connection, index) => (connection, index)) + .OrderBy(x => x.connection.PendingRequestCount) + .ThenBy(x => (tick + x.index) % candidates.Count) + .First() + .connection; } /// The only open connection, or null when zero or more than one client is connected.