Skip to content

Commit 996a40a

Browse files
authored
Limit Client Connections (#828)
* expose connection limit option * implement connection limit at handle new connection * addressing comments * fix unlimited connection limit * release v1.0.45
1 parent eeec78c commit 996a40a

File tree

6 files changed

+25
-5
lines changed

6 files changed

+25
-5
lines changed

Version.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<!-- Versioning property for builds and packages -->
33
<PropertyGroup>
4-
<VersionPrefix>1.0.44</VersionPrefix>
4+
<VersionPrefix>1.0.45</VersionPrefix>
55
</PropertyGroup>
66
</Project>

libs/host/Configuration/Options.cs

+5
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ internal sealed class Options
339339
[Option("maxthreads", Required = false, HelpText = "Maximum worker and completion threads in thread pool, 0 uses the system default.")]
340340
public int ThreadPoolMaxThreads { get; set; }
341341

342+
[IntRangeValidation(-1, int.MaxValue)]
343+
[Option("network-connection-limit", Required = false, Default = -1, HelpText = "Maximum number of simultaneously active network connections.")]
344+
public int NetworkConnectionLimit { get; set; }
345+
342346
[OptionValidation]
343347
[Option("use-azure-storage", Required = false, HelpText = "Use Azure Page Blobs for storage instead of local storage.")]
344348
public bool? UseAzureStorage { get; set; }
@@ -676,6 +680,7 @@ public GarnetServerOptions GetServerOptions(ILogger logger = null)
676680
QuietMode = QuietMode.GetValueOrDefault(),
677681
ThreadPoolMinThreads = ThreadPoolMinThreads,
678682
ThreadPoolMaxThreads = ThreadPoolMaxThreads,
683+
NetworkConnectionLimit = NetworkConnectionLimit,
679684
DeviceFactoryCreator = useAzureStorage
680685
? () => new AzureStorageNamedDeviceFactory(AzureStorageConnectionString, logger)
681686
: () => new LocalStorageNamedDeviceFactory(useNativeDeviceLinux: UseNativeDeviceLinux.GetValueOrDefault(), logger: logger),

libs/host/GarnetServer.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ private void InitializeServer()
216216
}
217217

218218
// Create Garnet TCP server if none was provided.
219-
this.server ??= new GarnetServerTcp(opts.Address, opts.Port, 0, opts.TlsOptions, opts.NetworkSendThrottleMax, logger);
219+
this.server ??= new GarnetServerTcp(opts.Address, opts.Port, 0, opts.TlsOptions, opts.NetworkSendThrottleMax, opts.NetworkConnectionLimit, logger);
220220

221221
storeWrapper = new StoreWrapper(version, redisProtocolVersion, server, store, objectStore, objectStoreSizeTracker,
222222
customCommandManager, appendOnlyFile, opts, clusterFactory: clusterFactory, loggerFactory: loggerFactory);

libs/host/defaults.conf

+3
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@
251251
/* Maximum worker and completion threads in thread pool, 0 uses the system default. */
252252
"ThreadPoolMaxThreads" : 0,
253253

254+
/* Maximum number of simultaneously active network connections. */
255+
"NetworkConnectionLimit" : -1,
256+
254257
/* Use Azure Page Blobs for storage instead of local storage. */
255258
"UseAzureStorage" : false,
256259

libs/server/Servers/GarnetServerOptions.cs

+5
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ public class GarnetServerOptions : ServerOptions
246246
/// </summary>
247247
public int ThreadPoolMaxThreads = 0;
248248

249+
/// <summary>
250+
/// Maximum client connection limit
251+
/// </summary>
252+
public int NetworkConnectionLimit = -1;
253+
249254
/// <summary>
250255
/// Creator of device factories
251256
/// </summary>

libs/server/Servers/GarnetServerTcp.cs

+10-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class GarnetServerTcp : GarnetServerBase, IServerHook
2424
readonly int networkSendThrottleMax;
2525
readonly NetworkBufferSettings networkBufferSettings;
2626
readonly LimitedFixedBufferPool networkPool;
27+
readonly int networkConnectionLimit;
2728

2829
public IPEndPoint GetEndPoint
2930
{
@@ -69,9 +70,10 @@ public IEnumerable<IClusterSession> ActiveClusterSessions()
6970
/// <param name="tlsOptions"></param>
7071
/// <param name="networkSendThrottleMax"></param>
7172
/// <param name="logger"></param>
72-
public GarnetServerTcp(string address, int port, int networkBufferSize = default, IGarnetTlsOptions tlsOptions = null, int networkSendThrottleMax = 8, ILogger logger = null)
73+
public GarnetServerTcp(string address, int port, int networkBufferSize = default, IGarnetTlsOptions tlsOptions = null, int networkSendThrottleMax = 8, int networkConnectionLimit = -1, ILogger logger = null)
7374
: base(address, port, networkBufferSize, logger)
7475
{
76+
this.networkConnectionLimit = networkConnectionLimit;
7577
this.tlsOptions = tlsOptions;
7678
this.networkSendThrottleMax = networkSendThrottleMax;
7779
var serverBufferSize = BufferSizeUtils.ServerBufferSize(new MaxSizeSettings());
@@ -134,11 +136,11 @@ private unsafe bool HandleNewConnection(SocketAsyncEventArgs e)
134136
string remoteEndpointName = e.AcceptSocket.RemoteEndPoint?.ToString();
135137
logger?.LogDebug("Accepted TCP connection from {remoteEndpoint}", remoteEndpointName);
136138

137-
138139
ServerTcpNetworkHandler handler = null;
139140
if (activeHandlerCount >= 0)
140141
{
141-
if (Interlocked.Increment(ref activeHandlerCount) > 0)
142+
var currentActiveHandlerCount = Interlocked.Increment(ref activeHandlerCount);
143+
if (currentActiveHandlerCount > 0 && (networkConnectionLimit == -1 || currentActiveHandlerCount <= networkConnectionLimit))
142144
{
143145
try
144146
{
@@ -157,6 +159,11 @@ private unsafe bool HandleNewConnection(SocketAsyncEventArgs e)
157159
handler?.Dispose();
158160
}
159161
}
162+
else
163+
{
164+
Interlocked.Decrement(ref activeHandlerCount);
165+
e.AcceptSocket.Dispose();
166+
}
160167
}
161168
return true;
162169
}

0 commit comments

Comments
 (0)