-
Notifications
You must be signed in to change notification settings - Fork 184
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
Expose SocketOption
querying on ConnectionContext
API
#950
Conversation
public void tcpStandardSocketOptionIsNotNull() throws Exception { | ||
testSocketOption("TCP_NODELAY", Boolean.class, is(notNullValue()), | ||
// HTTP_2 stream channel does not have TCP_NODELAY option | ||
protocol == Protocol.HTTP_2 ? equalTo("null") : not(equalTo("null"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Server connection context uses child-stream for h2 that does not allow users to query multiple TCP options for the original parent connection, like TCP_NODELAY
/ SO_RCVBUF
/ SO_SNDBUF
/ etc.
Do we want to keep it as-is? We can expose options for the original TCP connection by keeping ref for the parent's ChannelConfig
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any options for H2 that are applicable for a stream? If not, should we always just query the options from the parent context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I see in netty, it creates a new DefaultChannelConfig
for each stream. And these config is a fresh new and is not related to the parent's ChannelConfig
. Therefore, each channel has its own subset of options. In theory (but not in the current ST) some code may modify that options for each stream independently (like AUTO_READ,
AUTO_CLOSE`, etc.) and it will not have side-effects for parent channel.
I think it will be more practical for users to be interested in parent channel options. It will require one more reference in DefaultNettyConnection
. Let me try and will see the overhead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: 4fbb1f9
JDK11 build failed due to docker issue @servicetalk-bot test this please |
One of the builds failed with #952 |
...-netty-internal/src/main/java/io/servicetalk/transport/netty/internal/SocketOptionUtils.java
Outdated
Show resolved
Hide resolved
servicetalk-transport-api/src/main/java/io/servicetalk/transport/api/ConnectionContext.java
Show resolved
Hide resolved
if (option == ServiceTalkSocketOptions.IDLE_TIMEOUT) { | ||
return idleTimeoutMs == null ? null : (T) idleTimeoutMs; // TODO: return (T) idleTimeoutMs; | ||
} | ||
// Try to look for a ChannelOption with the same name and type: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the method above we do not set any option that we do not recognize in the channel config then is trying to lookup for an unknown value here reasonable? Can we be consistent between get
and set
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Netty has a lot more other options that users might be interested in to query, especially for different transports, like TCP_FASTOPEN_CONNECT
for epoll. See EpollChannelOption
class from netty.
If we will follow the policy to be consistent between get
and set
, every time users request a new option for querying we will need to provide one more ServiceTalkSocketOption
constant and implement support for setting this option. However, users may not bother with setting it, just querying. Also, maintaining a single or separate lists of ServiceTalkSocketOption
constants that are applicable only for a specific transport may be not ideal.
SocketOption<T>
is a public JDK API. Users can use it to create the required options for querying without asking us. The only risk here is that they can take internal ByteBufAllocator
from netty. But that will be their risky choice or we can prevent specific options from querying. The list is short and contains only 3 options that are dengerous: ALLOCATOR
, RCVBUF_ALLOCATOR
, MESSAGE_SIZE_ESTIMATOR
. All other netty options are read-only objects.
Considering that overhead of keeping get
and set
in consistency for every new option, I decided to let users query what they want with existing API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...-netty-internal/src/main/java/io/servicetalk/transport/netty/internal/SocketOptionUtils.java
Outdated
Show resolved
Hide resolved
...-netty-internal/src/main/java/io/servicetalk/transport/netty/internal/SocketOptionUtils.java
Show resolved
Hide resolved
} | ||
|
||
private DefaultNettyConnection(Channel channel, BufferAllocator allocator, Executor executor, | ||
TerminalPredicate<Read> terminalMsgPredicate, CloseHandler closeHandler, | ||
FlushStrategy flushStrategy, ExecutionStrategy executionStrategy, | ||
@Nullable SSLSession sslSession) { | ||
FlushStrategy flushStrategy, @Nullable Long idleTimeoutMs, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am somewhat apprehensive about individually adding options here which are otherwise not stored by netty. Anything else we add will mean we add more arguments here.
Can we instead take+store the TcpConfig
here and pass the same to SocketOptionUtils
for querying? If we do use TcpConfig
we can use that to also get the FlushStrategy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought about that but decided to defer until we add anything else to better understand how to structure it (maybe it will be better to have an object to keep these options instead of using the full TcpConfig
).
We do not expose AbstractReadOnlyTcpConfig
as a public class for now. If you think we can make AbstractReadOnlyTcpConfig
public (it lives in tcp-netty-internal
module) to keep DefaultNettyConnection
reusable for client and server side, I can do the change now. Otherwise, let's defer?
We may also consider using a single ExecutionContext
instead of other 3 separate arguments: BufferAllocator
, Executor
, ExecutionStrategy
. Can do here or as a follow-up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just use TcpConfig
for now as these are internal classes and we can make sure we do not update config? If you want, we can also wrap the config to throw from the setters.
I am also OK to defer, your call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will defer that, thanks
public void tcpStandardSocketOptionIsNotNull() throws Exception { | ||
testSocketOption("TCP_NODELAY", Boolean.class, is(notNullValue()), | ||
// HTTP_2 stream channel does not have TCP_NODELAY option | ||
protocol == Protocol.HTTP_2 ? equalTo("null") : not(equalTo("null"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any options for H2 that are applicable for a stream? If not, should we always just query the options from the parent context?
Motivation:
Users should be able to read socket options for created connections.
Modifications:
ConnectionContext.socketOption
API to query socket options;ConnectionContextSocketOptionTest
to test new API;Results:
Users can read socket options of the connections.