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

Shutting down the outbound side of the channel should not accept futu… #7041

Closed
wants to merge 1 commit into from

Conversation

Scottmitch
Copy link
Member

…re writes

Motivation:
Implementations of DuplexChannel delegate the shutdownOutput to the underlying transport, but do not take any action on the ChannelOutboundBuffer. In the event of a write failure due to the underlying transport failing and application may attempt to shutdown the output and allow the read side the transport to finish and detect the close. However this may result in an issue where writes are failed, this generates a writability change, we continue to write more data, and this may lead to another writability change, and this loop may continue. Shutting down the output should fail all pending writes and not allow any future writes to avoid this scenario.

Modifications:

  • Implementations of DuplexChannel should null out the ChannelOutboundBuffer and fail all pending writes

Result:
More controlled sequencing for shutting down the output side of a channel.

@Scottmitch Scottmitch self-assigned this Aug 1, 2017
Copy link
Member

@normanmaurer normanmaurer left a comment

Choose a reason for hiding this comment

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

Can you also add a testcase ?

/**
* Used to fail pending writes when a channel's output has been shutdown.
*/
public class ChannelOutputShutdownException extends java.io.IOException {
Copy link
Member

Choose a reason for hiding this comment

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

Just import IOException?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@@ -247,6 +247,7 @@ public void run() {
private void shutdownOutput0(final ChannelPromise promise) {
try {
shutdownOutput0();
Copy link
Member

Choose a reason for hiding this comment

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

Can't we move the unsafe call to shutdownOutput0() ?

@@ -663,6 +663,10 @@ public void run() {
clearNioBuffers();
}

void close(final ClosedChannelException cause) {
close(cause, false);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: you can remove final

Copy link
Member Author

Choose a reason for hiding this comment

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

done (comment should be on the line above I'm guessing?)

@Scottmitch Scottmitch force-pushed the shutdown_output branch 2 times, most recently from 1dd62da to ccd33aa Compare August 1, 2017 20:53
try {
Boolean writability = writabilityQueue.takeLast();
assertEquals(isWritable, writability);
// TODO(scott): why do we get multiple writability changes here ... race condition?
Copy link
Member Author

Choose a reason for hiding this comment

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

@normanmaurer - note that while writing outside the event loop I'm getting more writability change notifications than expected. If you would also only expect to get two notifications (not writable after the write, then writable after the flush) then I can open an issue and investigate as a followup.

Copy link
Member

Choose a reason for hiding this comment

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

please do and assign to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

see #7053

ss.bind(newSocketAddress());
cb.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(2, 4));
ch = (SocketChannel) cb.handler(h).connect(ss.getLocalSocketAddress()).sync().channel();
assumeFalse(ch instanceof OioSocketChannel);
Copy link
Member Author

Choose a reason for hiding this comment

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

OIO doesn't do writability notifications the same way

Copy link
Member

Choose a reason for hiding this comment

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

please do open an issue and assign to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

@Scottmitch
Copy link
Member Author

Build failure appears to be unrelated ... captured in #3138 (comment)

@Scottmitch
Copy link
Member Author

Same build failure on a different host (Debian 7-1) https://garage.netty.io/teamcity/viewLog.html?buildId=22855&buildTypeId=pulls_netty&guest=1 ... not sure why this would be related yet ... needs more investigation.

try {
Boolean writability = writabilityQueue.takeLast();
assertEquals(isWritable, writability);
// TODO(scott): why do we get multiple writability changes here ... race condition?
Copy link

Choose a reason for hiding this comment

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

INFO Complete the task associated to this TODO comment. rule

// TODO(scott): why do we get multiple writability changes here ... race condition?
drainWritabilityQueue();
} catch (Throwable c) {
c.printStackTrace();
Copy link

Choose a reason for hiding this comment

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

CRITICAL Use a logger to log this exception. rule

Copy link
Member

Choose a reason for hiding this comment

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

please address.

@Scottmitch
Copy link
Member Author

no build failure this time ... kicking off another build.

@Scottmitch
Copy link
Member Author

no build failure ... kicking off another build (round 2)

/**
* Used to fail pending writes when a channel's output has been shutdown.
*/
public class ChannelOutputShutdownException extends IOException {
Copy link
Member

Choose a reason for hiding this comment

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

final

/**
* Used to fail pending writes when a channel's output has been shutdown.
*/
public class ChannelOutputShutdownException extends IOException {
Copy link
Member

Choose a reason for hiding this comment

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

also do you want to add @UnstableApi ?

…re writes

Motivation:
Implementations of DuplexChannel delegate the shutdownOutput to the underlying transport, but do not take any action on the ChannelOutboundBuffer. In the event of a write failure due to the underlying transport failing and application may attempt to shutdown the output and allow the read side the transport to finish and detect the close. However this may result in an issue where writes are failed, this generates a writability change, we continue to write more data, and this may lead to another writability change, and this loop may continue. Shutting down the output should fail all pending writes and not allow any future writes to avoid this scenario.

Modifications:
- Implementations of DuplexChannel should null out the ChannelOutboundBuffer and fail all pending writes

Result:
More controlled sequencing for shutting down the output side of a channel.
@Scottmitch
Copy link
Member Author

@normanmaurer - Comments addressed ... wdyt about #7041 (comment) ?

@normanmaurer
Copy link
Member

@Scottmitch like I said please open an issue and assign to me :)
#7041 (comment)

@Scottmitch
Copy link
Member Author

4.1 (237a4da) 4.0 (bc8ddd4)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants