Async IO: The future

WARNING Experimental code ahead!

So far, all the high level APIs we have been using have been of the blockingvariety. For example, the delay::ms function makes the processor wait for sometime to pass and during that wait the processor can’t perform any useful action.That’s just wasteful. These blocking APIs make it hard (or near impossible) towrite programs that have to “do more than a thing”.

The goal of this section will be to write a program that performs two concurrenttasks: the “echo server” we wrote in section 10 and the LED roulette we wrote insection 4.

To do that we’ll have to throw away the high level APIs we have been using. The“busy” waiting pattern (while !condition {}) we have been using must go aswell.

Instead we’ll be using a new API based on “futures”. We won’t be used thefutures crate that’s available in crates.io but a minimal version of thetrait:

  1. /// Trait for types which are a placeholder of a value that will become
  2. /// available at possible some later point in time.
  3. trait Future {
  4. type Item;
  5. /// Check if this future has completed
  6. fn poll(&mut self) -> Async<Self::Item>;
  7. /// Drive a future to its completion by continuously calling `poll`
  8. fn wait(mut self) -> Self::Item
  9. where Self: Sized
  10. {
  11. loop {
  12. if let Async::Ready(item) = self.poll() {
  13. return item;
  14. }
  15. }
  16. }
  17. }
  18. /// Return type of future, indicating whether a value is ready or not.
  19. enum Async<T> {
  20. NotReady,
  21. Ready(T),
  22. }