-
Notifications
You must be signed in to change notification settings - Fork 355
HTTP/2: add per-stream idle and lifetime timeouts to core multiplexer #581
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
base: master
Are you sure you want to change the base?
Conversation
|
At the moment we only expose connection-level timeouts (for example via IOReactorConfig socket and session timeouts); there is no existing notion of per-stream timeout in the HTTP/2 code. |
What about |
RequestConfig#setResponseTimeout IMO lives in the client API, while H2Config is a transport-level setting in Core. I would keep this change scoped to Core and then look at wiring responseTimeout onto an appropriate per-stream timeout in the httpclient5 layer as a follow-up |
|
@arturobernalg @rschmitt This timeout value / these timeout values must be settable / mutable at runtime exactly the same way as Socket read timeout. Just setting an initial value from a config bean is not good enough. At the client level the request execution pipeline could use that API to apply |
@ok2c Makes sense. I can treat the timeouts in H2Config as defaults and keep the actual per-stream timeout state on H2Stream. |
@arturobernalg I agree with @rschmitt that is the wrong place for timeout settings. Those are meant to be H2 protocol related configs. Please use connection socket timeout as an initial / default value. |
2f5d095 to
31bbf5b
Compare
|
|
I'd like to see HTTP/2 test coverage added to |
@rschmitt That is fair, but the feature would need to have been made available in an alpha release of core or the timeout tests would need to be ported to core. |
@rschmitt I’ve added an async core HTTP/2 socket-timeout test in httpcore5-testing ( |
|
@arturobernalg Please rebase this change-set off the latest master and I will review it |
c6364c8 to
d7b8e8b
Compare
@ok2c please take a look |
b60f8b0 to
ccf73f8
Compare
Ideally I'd like to see contract testing, i.e. the same test cases running for HTTP, HTTPS, h2, and h2c. This ensures that the high-level API behaves consistently across the various implementations; it's also a very effective way of asserting that the various config options are being propagated and applied correctly throughout the client's internals. This is most effectively done through tests in |
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Outdated
Show resolved
Hide resolved
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
Outdated
Show resolved
Hide resolved
| requestExecutionCommand.getExchangeHandler(), | ||
| requestExecutionCommand.getPushHandlerFactory(), | ||
| requestExecutionCommand.getContext())); | ||
| initializeStreamTimeouts(stream); |
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.
@arturobernalg This looks wrong. The idea is to let the callback from RequestExecutionCommand decide what is to be done upon stream initialization. The StreamControl should just provide a setter.
| } | ||
| } | ||
|
|
||
| if (lifetimeTimeout != null && lifetimeTimeout.isEnabled()) { |
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.
@arturobernalg What lifetimeTimeout could be good for? Why do we need it?
httpcore5-h2/src/main/java/org/apache/hc/core5/http2/H2StreamTimeoutException.java
Outdated
Show resolved
Hide resolved
|
@arturobernalg Please try to minimize changes to H2 protocol code. More functionality can be added incrementally at a later point. Try to keep it small and lean. |
084cab8 to
5cd4675
Compare
@ok2c please another pass |
ee03f78 to
e627911
Compare
|
@arturobernalg Better, but please look at all my comments |
8534aa0 to
8cf5233
Compare
@ok2c I’ve updated the patch to reflect your feedback. please let me know if I missed anything. |
@arturobernalg I seem unable to get the message across or articulate it correctly. The patch still does too much and in the wrong places. I am not in favor of applying the changes in their present state. I suggest we drop this pull request and revisit the issue at a later point. |
|
@arturobernalg Please see 64b89f2 |
oh. much simple and clean. |
|
@arturobernalg Feel free to re-open this pull request and re-base your changes off the latest master. |
|
@arturobernalg Please re-open and rebase this change-set off the latest master. This is presently more important than other open pull requests in core |
8cf5233 to
127a32f
Compare
@ok2c done |
...ore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/CancellableExecution.java
Outdated
Show resolved
Hide resolved
978dfae to
ce72c8c
Compare
Expose configuration via H2Config, throw H2StreamTimeoutException on expiry and keep the connection alive Extend test coverage and add an example client demonstrating timed-out and successful streams
; Handle cancelled SelectionKey in interestOps access
ce72c8c to
a500259
Compare
| return idleTimeout; | ||
| } | ||
|
|
||
| void setIdleTimeout(final Timeout idleTimeout) { |
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.
@arturobernalg Why are you still doing this? Please implement this method instead
@Override
public void setTimeout(final Timeout timeout) {
// not supported
}
This is how the timeout should get initialized. Please remove all your timeout initialization code. It is not needed.
| } | ||
|
|
||
| Timeout getLifetimeTimeout() { | ||
| return lifetimeTimeout; |
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.
@arturobernalg Why do we need it? What purpose does it serve?
Please remove it. Please focus on the most fundamental and useful scenario for now.
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.
Agreed. Let's solve one problem at a time
| @Override | ||
| public int getEventMask() { | ||
| return this.key.interestOps(); | ||
| try { |
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.
@arturobernalg Christ on cross. Why do you still have this?
This change introduces per-stream idle and lifetime timeouts enforced by the HTTP/2 core multiplexer. Streams that exceed the configured limits are reset with H2StreamTimeoutException, while the underlying HTTP/2 connection remains usable for other streams.
Configuration is exposed via H2Config.setStreamIdleTimeout and setStreamLifetimeTimeout and is disabled by default, so existing users see no behaviour change unless they opt in. H2Stream now tracks creation and last-activity timestamps, and AbstractH2StreamMultiplexer inspects those on I/O events to apply the timeouts without background threads.