Coroutines and async/await 146 3. We get an error of kind Would Block. If that's the case, we know that since we set the stream to non-blocking, the data isn't ready yet or there is more data but we haven't received it yet. In that case, we return Poll State::Not Ready to communicate that more calls to the poll are needed to finish the operation. 4. We get an error of kind Interrupted. This is a bit of a special case since reads can be interrupted by a signal. If it does, the usual way to handle the error is to simply try reading once more. 5. We get an error that we can't handle, and since our example does no error handling, we simply panic! There is one subtle thing I want to point out. We can view this as a very simple state machine with three states: Not started, indicated by self. stream being None Pending, indicated by self. stream being Some and a read to stream. read returning Would Block Resolved, indicated by self. stream being Some and a call to stream. read returning 0 bytes As you see, this model maps nicely to the states reported by the OS when trying to read our Tcp Stream. Most leaf futures such as this will be quite simple, and although we didn't make the states explicit here, it still fits in the state machine model that we're basing our coroutines around. Do all futures have to be lazy? A lazy future is one where no work happens before it's polled the first time. This will come up a lot if you read about futures in Rust, and since our own Future trait is based on that exact same model, the same question will arise here. The simple answer to this question is no! There is nothing that forces leaf futures, such as the one we wrote here, to be lazy. We could have sent the HTTP request when we called the Http::get function if we wanted to. If you think about it, if we did just that, it would have caused a potentially big change that would impact how we achieve concurrency in our program. The way it works now is that someone has to call poll at least one time to actually send the request. The consequence is that whoever calls poll on this future will have to call poll on many futures to kick off the operation if they want them to run concurrently. If we kicked off the operation immediately when the future was created, you could create many futures and they would all run concurrently even though you polled them to completion one by one. If you 