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

Add TransportConfig to control low level transport settings #3041

Merged
merged 2 commits into from
Aug 14, 2024

Conversation

idelpivnitskiy
Copy link
Member

Motivation:

Users need a way to change low-level Netty settings, like AdaptiveRecvByteBufAllocator parameters. In the future, we can use this interface for more similar settings without the need to change client/server builder.

Modifications:

  • Add TransportConfig and TransportConfigBuilder in transport-api module;
  • Add methods on SingleAddressHttpClientBuilder and HttpServerBuilder to let users pass TransportConfig;
  • Wire it up to propagate to Tcp[Client|Server]ChannelInitializer as TransportConfigInitializer;

Result:

Users can control AdaptiveRecvByteBufAllocator settings.

Motivation:

Users need a way to change low-level Netty settings, like
`AdaptiveRecvByteBufAllocator` parameters. In the future, we can use
this interface for more similar settings without the need to change
client/server builder.

Modifications:

- Add `TransportConfig` and `TransportConfigBuilder` in `transport-api`
module;
- Add methods on `SingleAddressHttpClientBuilder` and
`HttpServerBuilder` to let users pass `TransportConfig`;
- Wire it up to propagate to `Tcp[Client|Server]ChannelInitializer` as
`TransportConfigInitializer`;

Result:

Users can control `AdaptiveRecvByteBufAllocator` settings.
*
* @see TransportConfigBuilder
*/
public interface TransportConfig {
Copy link
Member Author

Choose a reason for hiding this comment

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

This config follows the patters of [Client|Server]SslConfig, ProxyConfig, RedirectConfig, and [H1|H2]ProtocolConfig by having an interface and a builder.

Copy link
Contributor

Choose a reason for hiding this comment

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

The interface as it stands currently assumes that all the options are supported by the implementing one. Of course just having netty they are naturally supported, but I wonder if we should start to document/devise a strategy if there is a transport in the future which does not support a specific option? i.e. maxReadAttemptsPerSelect assumes a non-blocking style eventloop with a selector

Copy link
Member Author

Choose a reason for hiding this comment

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

For ServiceTalk API I would consider it as highly unlikely scenario that we ever change transport implementation. If we do, it will worth the major version bump and then we can also deprecate options and move them on impl-specific variants. During the transition period, it will be fine if the new impl ignores these options and logs about it or throws an exception.

int maxReadAttemptsPerSelect();

/**
* Maximum number of bytes per read operation.
Copy link
Contributor

Choose a reason for hiding this comment

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

So combined with the above it would be maxReadPerSelect times maxBytesPerRead ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, that will be the upper bound. The receive allocator may decide to lower the bound, then it might be smaller.

*
* @see TransportConfigBuilder
*/
public interface TransportConfig {
Copy link
Contributor

Choose a reason for hiding this comment

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

The interface as it stands currently assumes that all the options are supported by the implementing one. Of course just having netty they are naturally supported, but I wonder if we should start to document/devise a strategy if there is a transport in the future which does not support a specific option? i.e. maxReadAttemptsPerSelect assumes a non-blocking style eventloop with a selector

Copy link
Contributor

@bryce-anderson bryce-anderson left a comment

Choose a reason for hiding this comment

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

This look correct to me but I share in @daschl's concern that this is highly specific to netty and potentially a foot-gun for users. Is there a chance we could simply set a better default, or does this need to be user configurable?

@idelpivnitskiy
Copy link
Member Author

Is there a chance we could simply set a better default, or does this need to be user configurable?

The current defaults that we have are considered to be the best for a typical workflow. However, there are specific users that receive heavy payloads. Those need to tune these values to read data more aggressively to maximize efficiency.

@idelpivnitskiy idelpivnitskiy merged commit 4d9ab77 into apple:main Aug 14, 2024
11 checks passed
@idelpivnitskiy idelpivnitskiy deleted the TransportConfig branch August 14, 2024 22:56
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