first second draft of background information

This commit is contained in:
Carl Fredrik Samson
2020-02-07 00:02:50 +01:00
parent a464846b73
commit 526921f5a6

View File

@@ -60,19 +60,26 @@ some I/O operation, and the executor where
## Futures ## Futures
Now, when we talk about futures I find it useful to make a distinction between Now, when we talk about futures I find it useful to make a distinction between
futures created by async functions `async fn() { ... }` and async blocks non-leaf futures and **leaf** futures.
`async { ... }` and **leaf** futures.
Runtimes create leaf `Futures`, and provides things like non-blocking sockets, Runtimes create leaf futures which represents a resource like a socket.
an event queue and so on. Operations on these resources, like a `Read` on a socket, will be non-blocking
and instead return a future which we call a leaf future since it's the future
which we're actually waiting on.
It's unlikely that you'll implement a leaf future yourself unless you're writing
a runtime, but we'll go through how they're constructed in this book as well.
Non-leaf futures is the kind of futures we as users of a runtime writes
ourselves using the `async` keyword to create a task which can be run on the
executor. Often, such a task will `await` a leaf future as one of many
operations to complete the task.
In theory, we could choose one `Reactor` and one `Executor` that have nothing The key to these tasks is that they're able to yield control to the runtime's
to do with each other besides that one creates leaf `Futures` and the other one scheduler and then resume execution again where it left off at a later point.
runs them, but in reality today you'll most often get both in a `Runtime`.
In contrast to leaf futures, these kind of futures is not themselves
waiting on some I/O resource.
Quite a bit of complexity attributed to `Futures` are actually complexity rooted Quite a bit of complexity attributed to `Futures` are actually complexity rooted
in runtimes. Creating an efficient runtime is hard. in runtimes. Creating an efficient runtime is hard.
@@ -84,27 +91,7 @@ The difference between Rust and other languages is that you have to make an
active choice when it comes to picking a runtime. Most often you'll just use active choice when it comes to picking a runtime. Most often you'll just use
the one provided for you. the one provided for you.
## Futures 1.0 and Futures 3.0 ## Before we move on
I'll not spend too much time on this, but it feels wrong to not mention that
there have been several iterations on how async should work in Rust.
`Futures 3.0` works with the relatively new `async/await` syntax in Rust and
it's what we'll learn.
Now, since this is rather recent, you can encounter creates that use `Futures 1.0`
still. This will get resolved in time, but unfortunately it's not always easy
to know in advance.
A good sign is that if you're required to use combinators like `and_then` then
you're using `Futures 1.0`.
While they're not directly compatible, there is a tool that let's you relatively
easily convert a `Future 1.0` to a `Future 3.0` and vice a versa. You can find
all you need in the [`futures-rs`][futures_rs] crate and all
[information you need here][compat_info].
## First things first
If you find the concepts of concurrency and async programming confusing in If you find the concepts of concurrency and async programming confusing in
general, I know where you're coming from and I have written some resources to general, I know where you're coming from and I have written some resources to