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

Disable idle stream timeout, allow it to be configured downstream #3742

Merged

Conversation

niloc132
Copy link
Member

Fixes #3733

*
*/
public int http2StreamIdleTimeoutOrDefault() {
return http2StreamIdleTimeout().orElse(0);
Copy link
Member Author

Choose a reason for hiding this comment

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

Need to fix the Javadoc here. The default is defined here, but I intend to also define it in the default .prop file:

  • Defining it here prevents downstream breakage in applications built on top of DHC, while still leaving a reasonable default, without changing any Java or properties files
  • Defining it in the .prop file allows it to be passed to a client if so configured (I don't intend to enable that by default at this time), so that in theory if a deployment sets a concrete value here, clients can be informed at what time their streams will end if they've had no traffic.

Ideally we would solve this config situation differently, but I think this is a good compromise?

Copy link
Member

Choose a reason for hiding this comment

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

Does 0 explicitly mean "don't ever idle timeout"?

Copy link
Member Author

@niloc132 niloc132 Apr 27, 2023

Choose a reason for hiding this comment

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

Any non-positive number is a legal value, and interpreted as "no timeout". Salient bit of Jetty:

        long streamIdleTimeout = getStreamIdleTimeout();
        if (streamIdleTimeout > 0)
            session.setStreamIdleTimeout(streamIdleTimeout);

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for clearing up that I was misreading this. I've updated the patch now to directly set our preferred timeout directly on each Http2 connection/session, rather than attempt to do it globally. I'll follow up with a bug report slash feature request to Jetty to see if this could be easier to use?

Copy link
Member

Choose a reason for hiding this comment

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

Great.

@@ -128,6 +134,15 @@ public int port() {
@Nullable
public abstract Boolean http1();

public abstract OptionalInt http2StreamIdleTimeout();
Copy link
Member

Choose a reason for hiding this comment

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

Can we make this an Optional<Duration> instead? (I was going to suggest OptionalLong to match #setStreamIdleTimeout(long), but think Duration is better.)

Copy link
Member

Choose a reason for hiding this comment

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

We can also have a @Check annotation to ensure the value makes sense (ie, I'm assuming negative timeouts should not be allowed.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Technically negative values are allowed.

Copy link
Member

Choose a reason for hiding this comment

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

Can this be Optional<Duration> instead? (Can still parse as long millis, that's fine.)

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd still vote no, unless we have a consumer that takes Duration (for example, move to ServerConfig and pass to a matching method there to use it in netty... which doesnt exist, and if it did, it would be long+TimeUnit).

Otherwise we're just building up extra checks to turn a number (as is our convention in every other timeout/duration) into an object, then right back into a number again.

Following jetty (and ServerBuilder), I will change this to a long, and add a Millis suffix to the name.

*
*/
public int http2StreamIdleTimeoutOrDefault() {
return http2StreamIdleTimeout().orElse(0);
Copy link
Member

Choose a reason for hiding this comment

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

Does 0 explicitly mean "don't ever idle timeout"?

@@ -26,6 +27,7 @@ public abstract class JettyConfig implements ServerConfig {
public static final int DEFAULT_PLAINTEXT_PORT = 10000;
public static final String HTTP_WEBSOCKETS = "http.websockets";
public static final String HTTP_HTTP1 = "http.http1";
public static final String HTTP_STREAM_TIMEOUT = "http2.stream.idleTimeout";
Copy link
Member

Choose a reason for hiding this comment

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

I think we should call this http2.stream.idleTimeoutMillis, or leave as-is and expect parsing to be done via java.time.Duration#parse

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I like Duration strings rather than big ints, but I'm hesitant to change this since we are pretty uniformly millis for other configs at this time.

Copy link
Member

Choose a reason for hiding this comment

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

Should we call this http2.stream.idleTimeoutMillis?

@devinrsmith devinrsmith added the release blocker A bug/behavior that puts is below the "good enough" threshold to release. label Apr 27, 2023
@devinrsmith
Copy link
Member

Afaict, this PR does not fix the issue for me. Looking at the code, it seems that org.eclipse.jetty.http2.HTTP2Session#setStreamIdleTimeout may essentially be a no-op w/ 0, or supplanted by other means of configuring it. (It's likely that it's an oversight from jetty embedded configurability, or we are trying to configuring jetty incorrectly.)

@devinrsmith
Copy link
Member

Note: setting org.eclipse.jetty.http2.HTTP2Session#setStreamIdleTimeout to > 0 seems to work, in the sense that it changes the 30s timeout we are seeing; it's just that 0 doesn't take.

Comment on lines +335 to +338
if (connection instanceof HTTP2ServerConnection) {
HTTP2Session session = (HTTP2Session) ((HTTP2Connection) connection).getSession();
session.setStreamIdleTimeout(config.http2StreamIdleTimeoutOrDefault());
}
Copy link
Member

Choose a reason for hiding this comment

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

I think a follow-up ticket to jetty would be good.

@@ -26,6 +27,7 @@ public abstract class JettyConfig implements ServerConfig {
public static final int DEFAULT_PLAINTEXT_PORT = 10000;
public static final String HTTP_WEBSOCKETS = "http.websockets";
public static final String HTTP_HTTP1 = "http.http1";
public static final String HTTP_STREAM_TIMEOUT = "http2.stream.idleTimeout";
Copy link
Member

Choose a reason for hiding this comment

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

Should we call this http2.stream.idleTimeoutMillis?

@@ -128,6 +134,15 @@ public int port() {
@Nullable
public abstract Boolean http1();

public abstract OptionalInt http2StreamIdleTimeout();
Copy link
Member

Choose a reason for hiding this comment

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

Can this be Optional<Duration> instead? (Can still parse as long millis, that's fine.)

@niloc132 niloc132 requested a review from devinrsmith May 1, 2023 16:16
@@ -104,6 +106,9 @@ public static Builder buildFromConfig(Configuration config) {
if (httpHttp1 != null) {
builder.http1(Boolean.parseBoolean(httpHttp1));
}
if (h2StreamIdleTimeout != null) {
builder.http2StreamIdleTimeout(Integer.parseInt(h2StreamIdleTimeout));
Copy link
Member

Choose a reason for hiding this comment

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

Long.parseLong?

Copy link
Member

@nbauernfeind nbauernfeind left a comment

Choose a reason for hiding this comment

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

No additional comments from me.

@niloc132 niloc132 merged commit 8ec7ac9 into deephaven:main May 2, 2023
@github-actions github-actions bot locked and limited conversation to collaborators May 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
configuration grpc jetty NoDocumentationNeeded release blocker A bug/behavior that puts is below the "good enough" threshold to release. ReleaseNotesNeeded Release notes are needed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

URI / java barrage subscription unexpectedly closed after 30 seconds
3 participants