Creating a proper runtime
So, if we visualize the degree of dependency between the different parts of our runtime, our current design could be described this way:

Figure 8.5 – Tight coupling between reactor and executor
If we want a loose coupling between the reactor and executor, we need an interface provided to signal the executor that it should wake up when an event that allows a future to progress has occurred. It’s no coincidence that this type is called Waker
(https://doc.rust-lang.org/stable/std/task/struct.Waker.html) in Rust’s standard library. If we change our visualization to reflect this, it will look something like this:

Figure 8.6 – A loosely coupled reactor and executor
It’s no coincidence that we land on the same design as what we have in Rust today. It’s a minimal design from Rust’s point of view, but it allows for a wide variety of runtime designs without laying...