Summary 135 The third method is more of theoretical importance; normally, you' d be happy to send the task to the thread pool that most runtimes provide. Most executors have a way to accomplish #1 using methods such as spawn_blocking. These methods send the task to a thread pool created by the runtime where you can either perform CPU-intensive tasks or blocking tasks that are not supported by the runtime. Summary So, in this short chapter, we introduced Rust's futures to you. Y ou should now have a basic idea of what Rust's async design looks like, what the language provides for you, and what you need to get elsewhere. Y ou should also have an idea of what a leaf future and a non-leaf future are. These aspects are important as they're design decisions built into the language. Y ou know by now that Rust uses stackless coroutines to model asynchronous operations, but since a coroutine doesn't do anything in and of itself, it's important to know that the choice of how to schedule and run these coroutines is left up to you. We'll get a much better understanding as we start to explain how this all works in detail as we move forward. Now that we've seen a high-level overview of Rust's futures, we'll start explaining how they work from the ground up. The next chapter will cover the concept of futures and how they're connected with coroutines and the async/await keywords in Rust. We'll see for ourselves how they represent tasks that can pause and resume their execution, which is a prerequisite to having multiple tasks be in progress concurrently, and how they differ from the pausable/resumable tasks we implemented as fibers/green threads in Chapter 5.