-
Notifications
You must be signed in to change notification settings - Fork 116
Recv from channel hangs forever if other party is gone #12
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
Comments
Aha, after looking into this I think it's relatively expected behavior. When an I/O object (like this channel) is converted to a blocking future then the only way for it to be guaranteed to get resolved is if the event loop is running in the background somewhere. Here, though, the event loop isn't running, so I believe it was just by luck that before this was resolved. If you change this to |
It doesn't help:
Still hangs. The problem with current bevaior (IMHO) is that if event loop is terminated for some reason (e. g. because of error), peers from others threads waiting for completion of some operation (e. g. response from server) simply hang instead of getting any error. Because channel is bound to event loop, I think destruction of event loop should invalidate all associated objects (channels), and any operations on these channel should produce an error. |
Oh sorry, to clarify I mean that for an I/O object to work the event loop it came from must still be alive somewhere. That is, because you drop How come the event loop is dropping early for you? It's intended that event loops are very long lived (for the entire lifetime of a program), and it's only cleaned up once the entire world is being torn down. |
I can think of two scenarios:
|
Ah ok it looks like we may be working with different models of when event loops are created perhaps then? The Additionally it's assumed that panics in each client are isolated from all others. The |
Suppose, your client is a command line database client. That database client has a single connection per process, so it has event loop that serves that single connection. All connection-protocol handling logic happens inside that event loop, and high level synchronous blocking logic (like reading from file system etc.) may happen in another threads, and they communicate via channels. If event loop dies, other threads blocking on channels need to be notified of that fact.
Catch panic won't help, if future itself is completed with error without panic. Or simply completed successfully because there no more things to to. Have a look at this example:
(I've created two channels because it is a demo, real example would be much larger). It server fails to bind on port (e. g. if you replace It reminds me problems of But the problem is unsolvable in Java, because Java has no RAII. And Rust has it. Why not take advantage of it to make API safer? |
Yes unfortunately this is just something that fundamentally isn't designed to work. The source of "blocking" here is the event loop, as that's what the channel is bound to. If that's destroyed, the the channel has no ability to actually block. What you'd want to use in a case like that is something like |
Channel should not block, it should immediately return an error.
Probably. I don't yet fully understand why different channels exist. Anyway, I simply don't understand your motivation. AFAIU, it is possible to just make receiver not to hang. It is described in #17 . I does not practically add any overhead and makes API safer. Why do not do it? |
Perhaps related to this issue, I have an anecdotal example, spending several hours debugging while the tokio-core just wouldn't work. No errors, no nothing, scheduled futures just won't run in production while working perfectly in a unit test. Turns out it had to do with initializing a |
@alexcrichton Awesome! |
This commit is targeted at solving tokio-rs/tokio-core#12 and incorporates the solution from tokio-rs/tokio-core#17. Namely the `need_read` and `need_write` functions on `PollEvented` now return an error when the connected reactor has gone away and the task cannot be blocked. This will typically naturally translate to errors being returned by various connected I/O objects and should help tear down the world in a clean-ish fashion.
Uh oh!
There was an error while loading. Please reload this page.
Code:
This test hangs. I cannot tell for sure, but seems like it worked (i. e. did not hang) two days ago.
The text was updated successfully, but these errors were encountered: