Http2ConnectionHandler to allow decoupling close(..) from GOAWAY graceful close#9094
Conversation
a527eac to
57f8cc5
Compare
There was a problem hiding this comment.
@ejona86 - there is some complexity related to preserving existing functionality and gracefulShutdownTimeoutMillis management (which we should re-asses for 5.0).
ejona86
left a comment
There was a problem hiding this comment.
Couple of comments for things that may get looked at, but overall LGTM
There was a problem hiding this comment.
To confirm I understand: this is a bug fix that was just noticed when messing with this PR. It isn't necessary for the new feature (any more than previously).
There was a problem hiding this comment.
A null promise was possible but wasn't likely (e.g. would have to come from the pipeline, or from the ChanntHandlerContext promise factory). However now we are explicitly passing null when we don't care about being notified when the operation completes (e.g. after we write a GOAWAY we don't really care about knowing when graceful close completes).
codec-http2/src/main/java/io/netty/handler/codec/http2/Http2ConnectionHandler.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Why can promise now be null? I don't see why this is done.
There was a problem hiding this comment.
yip this class (e.g. ClosingChannelFutureListener) is a bit overloaded as it manages 3 things: promise propagation (optional), timer management (optional), and connection closure. I debated breaking it up ... but decided to just leave it as is for now due to its internal nature and easy to change if necessary.
|
Oh! A present for me! Minor note: I'm not 100% confident we should have the gracefulShutdownTimeoutMillis convenience in the new http2 API, or what it should look like. The behavior of gracefulShutdownTimeoutMillis is sort of easy: you set a timer and call channel.close() when it expires. Although to do the goaway itself really well you would send a PING after the GOAWAY and when the PING ACK arrives send out the second GOAWAY. Although that needs a configuration value for when to timeout the ping and send a second GOAWAY anyway. We have this implemented in gRPC and use a hard-coded timeout of 10 seconds. The double-goaway is described in the RFC, but using PING was not. Of the two, the two-stage GOAWAY seems much more useful to implement in-library. Anyway, I'm rambling and it is just stuff to think about. |
I made a similar comment #9094 (comment) around the same time 👍. I agree it is better to move higher in the stack. The rational for filling out the implementation here is because it is already exposed in the public APIs for the frame/multiplex builders and just not hooked up. We could consider this as "broken" and mark it deprecated but I'm not sure if it does much damage to implement it as the APIs describe. Folks can always explicitly disable it (e.g. set to I also agree the wdyt? |
|
To be clear, my "minor note" was more about future direction vs holding up this PR. I'm not too worried about gracefulShutdownTimeoutMillis. It is easy to implement wherever we need it. If it isn't implemented in the builder, that may be a reason to remove it vs add it, but meh. I'm not really worried.
Yeah. I wouldn't necessarily say "5.0", but "later" SGTM and I'm fine if it only makes it into 5.0. It might just be a utility function. |
|
@Scottmitch please fix the leak :) |
normanmaurer
left a comment
There was a problem hiding this comment.
LGTM after leak is fixed
…eful close Motivation: Http2ConnectionHandler#close(..) always runs the GOAWAY and graceful close logic. This coupling means that a user would have to override Http2ConnectionHandler#close(..) to modify the behavior, and the Http2FrameCodec and Http2MultiplexCodec are not extendable so you cannot override at this layer. Ideally we can totally decouple the close(..) of the transport and the GOAWAY graceful closure process completely, but to preserve backwards compatibility we can add an opt-out option to decouple where the application is responsible for sending a GOAWAY with error code equal to NO_ERROR as described in https://tools.ietf.org/html/rfc7540#section-6.8 in order to initiate graceful close. Modifications: - Http2ConnectionHandler supports an additional boolean constructor argument to opt out of close(..) going through the graceful close path. - Http2FrameCodecBuilder and Http2MultiplexCodec expose gracefulShutdownTimeoutMillis but do not hook them up properly. Since these are already exposed we should hook them up and make sure the timeout is applied properly. - Http2ConnectionHandler's goAway(..) method from Http2LifecycleManager should initiate the graceful closure process after writing a GOAWAY frame if the error code is NO_ERROR. This means that writing a Http2GoAwayFrame from Http2FrameCodec will initiate graceful close. Result: Http2ConnectionHandler#close(..) can now be decoupled from the graceful close process, and immediately close the underlying transport if desired.
022bb86 to
2ffd428
Compare
|
@Scottmitch feel free to merge once satisfied (also please cherry-pick into master) |
…eful close (#9094) Motivation: Http2ConnectionHandler#close(..) always runs the GOAWAY and graceful close logic. This coupling means that a user would have to override Http2ConnectionHandler#close(..) to modify the behavior, and the Http2FrameCodec and Http2MultiplexCodec are not extendable so you cannot override at this layer. Ideally we can totally decouple the close(..) of the transport and the GOAWAY graceful closure process completely, but to preserve backwards compatibility we can add an opt-out option to decouple where the application is responsible for sending a GOAWAY with error code equal to NO_ERROR as described in https://tools.ietf.org/html/rfc7540#section-6.8 in order to initiate graceful close. Modifications: - Http2ConnectionHandler supports an additional boolean constructor argument to opt out of close(..) going through the graceful close path. - Http2FrameCodecBuilder and Http2MultiplexCodec expose gracefulShutdownTimeoutMillis but do not hook them up properly. Since these are already exposed we should hook them up and make sure the timeout is applied properly. - Http2ConnectionHandler's goAway(..) method from Http2LifecycleManager should initiate the graceful closure process after writing a GOAWAY frame if the error code is NO_ERROR. This means that writing a Http2GoAwayFrame from Http2FrameCodec will initiate graceful close. Result: Http2ConnectionHandler#close(..) can now be decoupled from the graceful close process, and immediately close the underlying transport if desired.
|
master (67518e3) |
Motivation:
Http2ConnectionHandler#close(..) always runs the GOAWAY and graceful close
logic. This coupling means that a user would have to override
Http2ConnectionHandler#close(..) to modify the behavior, and the
Http2FrameCodec and Http2MultiplexCodec are not extendable so you cannot
override at this layer. Ideally we can totally decouple the close(..) of the
transport and the GOAWAY graceful closure process completely, but to preserve
backwards compatibility we can add an opt-out option to decouple where the
application is responsible for sending a GOAWAY with error code equal to
NO_ERROR as described in https://tools.ietf.org/html/rfc7540#section-6.8 in
order to initiate graceful close.
Modifications:
opt out of close(..) going through the graceful close path.
gracefulShutdownTimeoutMillis but do not hook them up properly. Since these
are already exposed we should hook them up and make sure the timeout is applied
properly.
initiate the graceful closure process after writing a GOAWAY frame if the error
code is NO_ERROR. This means that writing a Http2GoAwayFrame from
Http2FrameCodec will initiate graceful close.
Result:
Http2ConnectionHandler#close(..) can now be decoupled from the graceful close
process, and immediately close the underlying transport if desired.