-
-
Notifications
You must be signed in to change notification settings - Fork 110
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
simplify transport. #296
simplify transport. #296
Conversation
A substantial amount of the complexity of the transport package is due the interface: we pass contexts to functions that do IO, and then jump through hoops to respect those contexts. Instead, this patch changes Transport and Codec's Close() to work like net.Close(): it interrupts any outstanding IO. We demand the same semantics from the io.ReadWriteCloser that we pass in, which seems like not a tall order. Still TODO: - [ ] rework the rpc subsystem's shutdown logic. The basic idea is we spawn an extra goroutine to wait on context.Done() and then call close, but the shutdown logic is intricate and I am too tired right now; this patch introduces test regressions for now. - [ ] Tweak the docs on how this changes the interface for e.g. NewConn
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 is a self-contained enough change that it seemed worth submitting independently of capnproto#296; this moves the actual IO calls on the transport into a new pair of goroutines (one for send, one for receive), so that the receive loop and the send goroutine can always be responsive to context cancels. This will become important when we no longer require the IO operations themselves to respond to a context.
This is a self-contained enough change that it seemed worth submitting independently of capnproto#296; this moves the actual RecvMessage() call on the transport into a new goroutines (one for send, one for receive), so that the receive loop always be responsive to context cancels. This will become important when we no longer require the IO operations themselves to respond to a context. send() can stay as-is; it would be abnormal for write to block indefinitely, so we can rely on that one to return in a reasonable amount of time. Meanwhile, the new reader goroutine is safe to leave running until late into the shutdown logic, since the shutdown logic doesn't itself want to read from the transport, and any messages read won't be acted on since the receive loop has shut down.
- Add a timeout during shutdown for aborts - Make sure we are actually reading from the channel
This is mostly working, but there are some intermittent test failures I don't fully understand yet. @lthibault, I think it's worth a look, though we shouldn't hit merge until we've nailed down those issues. As far as performance data; before:
After:
|
Presumably this couldn't happen before we added the timeout during shutdown, but now I am seeing an occasional panic here without this if.
This fixes some occasional test failures where questions were sent even though the context is canceled before the relevant functions were called; these are dependent on sendMessage to check the context before actually doing the send.
@lthibault, ok, I think this is ready. |
A substantial amount of the complexity of the transport package is due
the interface: we pass contexts to functions that do IO, and then jump
through hoops to respect those contexts. Instead, this patch changes
Transport and Codec's Close() to work like net.Close(): it interrupts
any outstanding IO. We demand the same semantics from the
io.ReadWriteCloser that we pass in, which seems like not a tall order.
Still TODO:
spawn an extra goroutine to wait on context.Done() and then call close,
but the shutdown logic is intricate and I am too tired right now; this
patch introduces test regressions for now.
Marking this as a draft for now, until I find time to tie up the loose ends.