I’m having trouble understanding how Tokio’s readiness-driven, I/O works. I’m studying the echo UDP sample.
I put some debug printlns in the example to print out the flow of events. This is a record of it running, annotated with the “conversation” I was having with it via “nc”:
# Initial startup, waiting for me to send it a datagram Listening on: 127.0.0.1:8080 poll() loop about to call recv_from() # After sending it a datagram, via the `nc(1)` utility poll() loop about to call recv_from() recv_from: Some((1, V4(127.0.0.1:65500))) loop Echoed 1/1 bytes to 127.0.0.1:65500 about to call recv_from() # A second message, again sent from `nc(1)` poll() loop about to call recv_from() recv_from: Some((22, V4(127.0.0.1:65500))) loop Echoed 22/22 bytes to 127.0.0.1:65500 about to call recv_from()
My confusion lies at the last part of each of these three stanzas. The code seems to stop near the end of the
poll() method, specifically at the call to
recv_from() while waiting for input.
On one hand,
recv_from() appears to block, because the
println that comes immediately after doesn’t get invoked. But when data does arrive, the
poll() method is invoked anew. So the
poll() function actually appears to have completed. This seems to make more sense, because all the Tokio funcitons are supposed to be non-blocking. But, I really don’t understand what happens when
recv_from() is called and there is nothing to read.
Some other, more general, questions are: what entity invokes the
poll() method and what informs that entity that
poll() should be called? Seems like understanding that is another key to making use of futures.