Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds customization options for SocketsHttpHandler #539

Merged
merged 4 commits into from
Feb 28, 2024

Conversation

malandis
Copy link
Contributor

@malandis malandis commented Feb 28, 2024

Overview

  1. Add SocketHttpHandler config options and plumb through.
  2. Set Lambda config to use SocketHttpHandler.PooledConnectionIdleTimeout
    of 6 minutes.
  3. Add target frameworks for .NET 6.0 and bump target framework net461
    to net462 for async iterator support.

SocketHttpHandler config

In Grpc.Net.Client, the default HttpHandler on .NET runtimes .NET
5.0 or greater is SocketsHttpHandler. In this PR we create a new
options class to encapsulate customizations to the handler, most
importantly the pooled connection timeout and whether to enable
multiple http connections.

Lambda config

The default value for the idle connection timeout is 1 minute. We find
this too strict in lambda environments, where the container may freeze
and thaw in greater than 1 minute spans but less than the server
timeout (5 minutes as of writing). Therefore we set the lambda config
pooled connection idle timeout higher, to 6 minutes. That way a lambda
function will not needlessly reconnect when the connection is still
open.

Target framework

Previously we relied on .NET Framework 4.61 as the .NET Framework
target. The next minor version introduced async iterator features
necessary for the topic client. Because of this, at the time, we added
preprocessor directives to exclude the topic client if the build target
wasn't .NET Standard 2.0 or greater.

Now that we add another target framework, .NET 6.0, maintaining the
different platform directives is difficult. Instead we bump the Framework
target from net461 to net462 to gain the async iterators and remove
the platform conditional compilation directives. There is no customer
impact by removing exactly .NET 4.61 as a target framework.

.NET 4.62 also includes WinHttpHandler, so we can revisit the use of
gRPC web in that Framework.

In `Grpc.Net.Client`, the default HttpHandler on .NET runtimes .NET
5.0 or greater is `SocketsHttpHandler`. In this PR we create a new
options class to encapsulate customizations to the handler, most
importantly the pooled connection timeout and whether to enable
multiple http connections.

The default value for the idle connection timeout is 1 minute. We find
this too strict in lambda environments, where the container may freeze
and thaw in greater than 1 minute spans but less than the server
timeout (5 minutes as of writing). Therefore we set the lambda config
pooled connection idle timeout higher, to 6 minutes. That way a lambda
function will not needlessly reconnect when the connection is still
open.
Previously we relied on .NET Framework 4.61 as the minimum
version. The next minor version introduced async iterator features
necessary for the topic client. Because of this, at the time, we added
preprocessor directives to exclude the topic client if the runtime
wasn't .NET Standard 2.0 or greater.

Now that we add another target framework, .NET 6.0, maintaining the
different platform directives is difficult. Instead we bump the target
framework from net461 to net462 to gain the async iterators and remove
the platform conditional compilation directives.
Copy link
Contributor Author

@malandis malandis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some clarifying comments. Lots of warnings leftover that we need to review.

Comment on lines +103 to +108
#if NET5_0_OR_GREATER
HttpHandler = new System.Net.Http.SocketsHttpHandler
{
EnableMultipleHttp2Connections = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.EnableMultipleHttp2Connections,
PooledConnectionIdleTimeout = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.PooledConnectionIdleTimeout
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where we set the SocketsHttpHandler settings for the control client

Comment on lines +287 to +292
#if NET5_0_OR_GREATER
channelOptions.HttpHandler = new SocketsHttpHandler
{
EnableMultipleHttp2Connections = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.EnableMultipleHttp2Connections,
PooledConnectionIdleTimeout = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.PooledConnectionIdleTimeout
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where we set the data client SocketsHttpHandler settings

@@ -379,8 +379,6 @@ public static TSuccess LogTraceCollectionRequestSuccess<TSuccess>(this ILogger _
}
return success;
}

#if NETSTANDARD2_0_OR_GREATER
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these NETSTANDARD2.0 directives are necessary anymore since I bumped the target framework from .NET 4.61 to .NET 4.62.

@@ -2,11 +2,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Build Configuration -->
<TargetFrameworks>netstandard2.0;net461</TargetFrameworks>
<TargetFrameworks>netstandard2.0;net6.0;net462</TargetFrameworks>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding net6.0 and bumping net 4.61 to 4.62.

Comment on lines -8 to -9
<!-- Microsoft.Bcl.AsyncInterfaces on net461 isn't supported; suppress warning -->
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer necessary since we are on net462

{
public static TimeSpan DefaultPooledConnectionIdleTimeout { get; } = TimeSpan.FromMinutes(1);
public TimeSpan PooledConnectionIdleTimeout { get; } = DefaultPooledConnectionIdleTimeout;
public bool EnableMultipleHttp2Connections { get; } = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if we needed in this PR and if true is default (should be but confirming). I am having a hard time connect this with gRPC as ideally the http2 control should be in the gRPC libraries.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EnableMultipleHttp2Connections = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.EnableMultipleHttp2Connections,
PooledConnectionIdleTimeout = config.TransportStrategy.GrpcConfig.SocketsHttpHandlerOptions.PooledConnectionIdleTimeout
};
#elif USE_GRPC_WEB
channelOptions.HttpHandler = new GrpcWebHandler(new HttpClientHandler());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay nice since the grpc handler takes this it shouldn't affect global state !

@malandis malandis merged commit 7408283 into main Feb 28, 2024
7 checks passed
@malandis malandis deleted the feat/sockets-http-handler-customizations branch February 28, 2024 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants