diff --git a/Client/src/Common/ArmoniK.DevelopmentKit.Client.Common.csproj b/Client/src/Common/ArmoniK.DevelopmentKit.Client.Common.csproj index 3afdfd79a..d36e7b183 100644 --- a/Client/src/Common/ArmoniK.DevelopmentKit.Client.Common.csproj +++ b/Client/src/Common/ArmoniK.DevelopmentKit.Client.Common.csproj @@ -8,7 +8,7 @@ - + diff --git a/Client/src/Common/Properties.cs b/Client/src/Common/Properties.cs index 5daf6e439..20d5ab245 100644 --- a/Client/src/Common/Properties.cs +++ b/Client/src/Common/Properties.cs @@ -53,6 +53,7 @@ public class Properties private const string SectionProxy = "Proxy"; private const string SectionProxyUsername = "ProxyUsername"; private const string SectionProxyPassword = "ProxyPassword"; + private const string SectionReusePorts = "ReusePorts"; private const string SectionRetryInitialBackoff = "RetryInitialBackoff"; private const string SectionRetryBackoffMultiplier = "RetryBackoffMultiplier"; @@ -127,6 +128,10 @@ public Properties(TaskOptions options, /// Initial retry backoff delay /// Retry backoff multiplier /// Max retry backoff + /// Proxy configuration + /// Username used for proxy authentication + /// Password used for proxy authentication + /// Enable the option SO_REUSE_UNICASTPORT upon socket opening to limit port exhaustion /// public Properties(IConfiguration configuration, TaskOptions options, @@ -143,7 +148,8 @@ public Properties(IConfiguration configuration, TimeSpan retryMaxBackoff = new(), string? proxy = null, string? proxyUsername = null, - string? proxyPassword = null) + string? proxyPassword = null, + bool? reusePorts = null) { TaskOptions = options; Configuration = configuration; @@ -195,6 +201,17 @@ public Properties(IConfiguration configuration, Proxy = proxy ?? sectionGrpc[SectionProxy] ?? string.Empty; ProxyUsername = proxyUsername ?? sectionGrpc[SectionProxyUsername] ?? string.Empty; ProxyPassword = proxyPassword ?? sectionGrpc[SectionProxyPassword] ?? string.Empty; + ReusePorts = reusePorts ?? sectionGrpc[SectionReusePorts] + ?.ToLower() switch + { + null or "" => true, + "true" or "yes" or "enable" => true, + "false" or "no" or "disable" => false, +#pragma warning disable CA2208 + var val => throw new ArgumentException($"\"{val}\" is not a valid boolean", + SectionReusePorts), +#pragma warning restore CA2208 + }; if (retryInitialBackoff != TimeSpan.Zero) { @@ -393,4 +410,9 @@ public string ConnectionString /// Password for the proxy /// public string ProxyPassword { get; set; } + + /// + /// Enable the option SO_REUSE_UNICASTPORT upon socket opening to limit port exhaustion + /// + public bool ReusePorts { get; set; } } diff --git a/Client/src/Common/Submitter/ClientServiceConnector.cs b/Client/src/Common/Submitter/ClientServiceConnector.cs index 26e71c3fe..06ac8db8e 100644 --- a/Client/src/Common/Submitter/ClientServiceConnector.cs +++ b/Client/src/Common/Submitter/ClientServiceConnector.cs @@ -55,6 +55,7 @@ public static ObjectPool ControlPlaneConnectionPool(Properties Proxy = properties.Proxy, ProxyUsername = properties.ProxyUsername, ProxyPassword = properties.ProxyPassword, + ReusePorts = properties.ReusePorts, }; return new ObjectPool(ct => new ValueTask(GrpcChannelFactory.CreateChannel(options, diff --git a/Tests/ArmoniK.EndToEndTests/ArmoniK.EndToEndTests.Common/ArmoniK.EndToEndTests.Common.csproj b/Tests/ArmoniK.EndToEndTests/ArmoniK.EndToEndTests.Common/ArmoniK.EndToEndTests.Common.csproj index 8cbb879ea..d3a18dc91 100644 --- a/Tests/ArmoniK.EndToEndTests/ArmoniK.EndToEndTests.Common/ArmoniK.EndToEndTests.Common.csproj +++ b/Tests/ArmoniK.EndToEndTests/ArmoniK.EndToEndTests.Common/ArmoniK.EndToEndTests.Common.csproj @@ -12,7 +12,7 @@ - + diff --git a/Worker/src/Common/ArmoniK.DevelopmentKit.Worker.Common.csproj b/Worker/src/Common/ArmoniK.DevelopmentKit.Worker.Common.csproj index b6cdd6d61..092a3f7a0 100644 --- a/Worker/src/Common/ArmoniK.DevelopmentKit.Worker.Common.csproj +++ b/Worker/src/Common/ArmoniK.DevelopmentKit.Worker.Common.csproj @@ -8,7 +8,7 @@ - +