-
Notifications
You must be signed in to change notification settings - Fork 656
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Synchronous connection failures must close channels. #329
Conversation
Sources/NIO/BaseSocketChannel.swift
Outdated
promise?.fail(error: error) | ||
assert(self.isOpen) | ||
// We're going to set the promise as the pending connect promise, and let close0 fail it for us. | ||
self.pendingConnect = promise |
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.
@Lukasa this actually made me aware of another issue (which we may want to handle in another issue tho..). The pendingConnect is currently failed after
we call fireChannelInactive which I think is not what should be done as the promise should be notified before the callbacks imho.
Sources/NIO/BaseSocketChannel.swift
Outdated
@@ -917,7 +917,10 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore { | |||
becomeActive0(promise: promise) | |||
} | |||
} catch let error { | |||
promise?.fail(error: error) | |||
assert(self.isOpen) |
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 other places we opted to go for assert(self.lifecycleManager.isRegistered)
. Maybe you also want to assert(!self.lifecycleManager.isActive)
because we should be registered but not active here.
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.
That assertion is unnecessary because the do
block covers it. I suppose I could assert isRegistered && !isActive
, if you prefer.
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.
looks pretty good, two nits
Tests/NIOTests/ChannelTests.swift
Outdated
@@ -83,6 +83,41 @@ class ChannelLifecycleHandler: ChannelInboundHandler { | |||
} | |||
} | |||
|
|||
fileprivate class VerifyConnectionFailureHandler: ChannelInboundHandler { |
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.
would you mind putting this class at the bottom of the file? I don't really like when I need to search for the beginning of the actual test class as that is where Xcode puts the 'run all tests in this class' button. I think our test files should all start with the actual test class and not the helpers.
e3c5670
to
57e9460
Compare
Ok @weissi, feedback addressed. |
Sources/NIO/BaseSocketChannel.swift
Outdated
@@ -917,7 +916,10 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore { | |||
becomeActive0(promise: promise) | |||
} | |||
} catch let error { | |||
promise?.fail(error: error) | |||
assert(self.lifecycleManager.isRegistered && !self.lifecycleManager.isActive) |
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.
sorry, tiny nit, would you mind putting them in different lines asserts? As if one fails, the assertion message won't tell you what went wrong. Otherwise you'd need to add a message printing both :(
57e9460
to
eafa908
Compare
Motivation: When a connect() call returns an error other than EINPROGRESS, we currently leave the FD registered and don't close the channel. This is wrong, we should take this as a signal to close the socket immediately, rathern than letting the selector tell us this FD is dead: after all, we know it's dead. Modifications: Call `close0()` in synchronous connect failures. Result: Faster failures!
ACK, feedback addressed. |
eafa908
to
0ad42c3
Compare
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.
awesome, ta
Motivation:
When a connect() call returns an error other than EINPROGRESS, we
currently leave the FD registered and don't close the channel. This is
wrong, we should take this as a signal to close the socket immediately,
rathern than letting the selector tell us this FD is dead: after all,
we know it's dead.
Modifications:
Call
close0()
in synchronous connect failures.Result:
Faster failures!
Resolves #322.