? 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