diff --git a/packages/csharp/ArmoniK.Api.Client/Options/GrpcClient.cs b/packages/csharp/ArmoniK.Api.Client/Options/GrpcClient.cs
index 83cae164f..5bef708fd 100644
--- a/packages/csharp/ArmoniK.Api.Client/Options/GrpcClient.cs
+++ b/packages/csharp/ArmoniK.Api.Client/Options/GrpcClient.cs
@@ -154,5 +154,10 @@ public bool HasClientCertificate
/// Password used for proxy authentication
///
public string ProxyPassword { get; set; } = "";
+
+ ///
+ /// Enable the option SO_REUSE_UNICASTPORT upon socket opening to limit port exhaustion
+ ///
+ public bool ReusePorts { get; set; } = true;
}
}
diff --git a/packages/csharp/ArmoniK.Api.Client/Submitter/GrpcChannelFactory.cs b/packages/csharp/ArmoniK.Api.Client/Submitter/GrpcChannelFactory.cs
index da3828806..24b7515af 100644
--- a/packages/csharp/ArmoniK.Api.Client/Submitter/GrpcChannelFactory.cs
+++ b/packages/csharp/ArmoniK.Api.Client/Submitter/GrpcChannelFactory.cs
@@ -274,6 +274,11 @@ private static GrpcChannel CreateChannelInternal(GrpcClient optionsGrpcClient,
throw new InvalidOperationException($"{nameof(optionsGrpcClient.Endpoint)} should not be null or empty");
}
+ if (optionsGrpcClient.ReusePorts)
+ {
+ ServicePointManager.ReusePort = true;
+ }
+
var serviceConfig = new ServiceConfig
{
MethodConfigs =
@@ -389,6 +394,8 @@ private static GrpcChannel CreateChannelInternal(GrpcClient optionsGrpcClient,
proxyType,
handlerType,
logger);
+ httpHandler = new Handler(httpHandler,
+ logger);
// Warn that RequestTimeout is not supported.
// If required, it could be easily implemented with a DelegatingHandler and a cancellationToken delayed cancellation
@@ -625,5 +632,30 @@ private enum HandlerType
///
Web,
}
+
+ private class Handler : DelegatingHandler
+ {
+ private readonly ILogger? logger_;
+
+ internal Handler(HttpMessageHandler inner,
+ ILogger? logger)
+ : base(inner)
+ => logger_ = logger;
+
+ protected override async Task SendAsync(HttpRequestMessage request,
+ CancellationToken cancellationToken)
+ {
+ var response = await base.SendAsync(request,
+ cancellationToken)
+ .ConfigureAwait(false);
+
+ if (response.Headers.ConnectionClose is true)
+ {
+ logger_?.LogInformation("Connection closing has been requested, performance degradation is expected");
+ }
+
+ return response;
+ }
+ }
}
}