? is an alternative to try! and unwrap() in Rust. There is a problem where some calls will block and we don’t get to use CPU cycles while waiting.

Threads can be fine if you have some other work to do but using Threads lead to:

  • Race conditions
  • Overhead due to per-thread stacks
  • Limitations due to max threads

The solution to this problem is non-blocking IO (tokio). There are two ways to find out if I/O is ready to be queried.

Four Choices for AIO

Blocking IO 1 Process per Request

Old:

  • Main thread waits for connections
  • Upon connect, forks off a new process
  • Each IO request is blocking Advantages:
  • Simple to understand and easy to program Disadvantages:
  • High overhead from starting 1000s of processes

Blocking IO 1 Thread per Request

Threads are more lightweight than processes. Same as 1 process per request but more lightweight. IO is the same but still blocking.
Advantages:

  • Still simple to understand Disadvantages:
  • There are race conditions now on shared data
  • Overhead still

Async IO with a Pool of Threads

Basic workflow:

  • Enqueue a request
  • Do something else…
  • Periodically check whether a request is done
  • Read return value

Nonblocking IO with a Pool of Threads