-
Notifications
You must be signed in to change notification settings - Fork 719
Ensure we always update the promise before calling fire* methods and … #181
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
Conversation
Lukasa
left a comment
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.
Cool, so this is basically pretty good! I'd like to see this test pulled out to its own file so you can declare the lifecycle handlers outside the test function, but otherwise this is basically good (plus notes).
Sources/NIO/SocketChannel.swift
Outdated
| try socket.close() | ||
| } catch { | ||
| promise?.fail(error: error) | ||
| return |
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.
Wait, why are we returning here? If we fail to close the socket we don't cancel the pending writes?
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.
maybe we should still do ... Good question. I guess there is not much we can do in this case.
Tests/NIOTests/ChannelTests.swift
Outdated
| XCTAssertTrue(closePromise.futureResult.fulfilled, "closePromise not fullfilled before channelInactive was called") | ||
| } else { | ||
| XCTFail("close(...) not called before channelInactive") | ||
| } |
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.
We can reduce this duplicate code by writing a pair of helper functions:
func assertFulfilled(promise: EventLoopPromise<Void>?, promiseName: String, trigger: String, setter: String, file: String = #file, line: Uint = #line) {
if let promise = promise {
XCTAssertTrue(promise.futureResult.fulfilled, "\(promiseName) not fulfilled before \(trigger) was called", file: file, line: line)
} else {
XCTFail("\(setter) not called before \(trigger)", file: file, line: line
}
}This would let us truncate this file substantially and better express the criteria of these assertions.
Tests/NIOTests/ChannelTests.swift
Outdated
| XCTAssertNil(self.connectPromise) | ||
| XCTAssertNil(self.closePromise) | ||
|
|
||
| promise?.futureResult.whenSuccess { |
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.
Do you actually accept this promise being nil?
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.
nope it should not be null ever so I think we can just make it a force unwrap.
Tests/NIOTests/ChannelTests.swift
Outdated
| XCTAssertNil(self.connectPromise) | ||
| XCTAssertNil(self.closePromise) | ||
|
|
||
| promise?.futureResult.whenSuccess { |
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.
Or this one?
Tests/NIOTests/ChannelTests.swift
Outdated
| XCTAssertNotNil(self.connectPromise) | ||
| XCTAssertNil(self.closePromise) | ||
|
|
||
| promise?.futureResult.whenSuccess { |
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.
Or this one?
87694f5 to
a4fd3a1
Compare
|
@Lukasa I think I addressed all of your comments (hopefully). |
| p = promise | ||
| } catch { | ||
| promise?.fail(error: error) | ||
| p = nil |
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.
This code cannot possibly be right. What's the intended behaviour here?
| p = promise | ||
| } catch { | ||
| promise?.fail(error: error) | ||
| p = nil |
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.
ok let me explain what I wanted to do ... Basically because we fail the promise here I wanted to ensure we pass nil to becomeInactive0 so we not try to notify the promise again.
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.
Ah, ok. Please put a comment to that effect 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.
done
…also udate channel state before. Motivation: We not always ensure correct ordering which made it quite hard to reason about things. We should always first notify the promise before we call the fire* method that belongs to the event. Beside this we sometimes fired events or notified promised before correctly update the active state / addresses of a Channel which could result in unexpected results when query the Channel during execution of callbacks and handlers. Modifications: - Ensure we always notify promise first - Always correctly update channel state before notify promise - Add test to verify notification order. Result: Correct ordering of events which makes things easier to reason about and which follows what netty is doing.
a4fd3a1 to
f4811b7
Compare
…also udate channel state before.
Motivation:
We not always ensure correct ordering which made it quite hard to reason about things. We should always first notify the promise before we call the fire* method that belongs to the event. Beside this we sometimes fired events or notified promised before correctly update the active state / addresses of a Channel which could result in unexpected results when query the Channel during execution of callbacks and handlers.
Modifications:
Result:
Correct ordering of events which makes things easier to reason about and which follows what netty is doing.