Skip to content

Commit

Permalink
use cargo add when adding dependencies
Browse files Browse the repository at this point in the history
This picks specific latest x.y.z version available, which is generally
what most users should be doing when writing new applications rather
than choosing a general version. This builds upon the tokio website
dependencies being automatically updated by dependabot. If these fail to
build in a particular version, then these cargo add commands should be
temporarily changed to pin specific versions. However, this should be
rare.
  • Loading branch information
joshka committed Oct 18, 2024
1 parent 3c1522c commit f730990
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 27 deletions.
22 changes: 10 additions & 12 deletions content/tokio/topics/tracing-next-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ performance issues during the development process.
For instance, to use tokio-console in [the mini-redis project](https://github.com/tokio-rs/mini-redis),
you need to enable the `tracing` feature for the Tokio package:

```toml
# Update the tokio import in your Cargo.toml
tokio = { version = "1", features = ["full", "tracing"] }
```bash
cargo add tokio --features full,tracing
```

Note: The `full` feature doesn't enable `tracing`.
Expand All @@ -23,9 +22,8 @@ You'll also need to add a dependency on the `console-subscriber` package. This
crate provides a `Subscriber` implementation that will replace the one currently
used by mini-redis:

```toml
# Add this to the dependencies section of your Cargo.toml
console-subscriber = "0.1.5"
```bash
cargo add console-subscriber
```

Finally, in `src/bin/server.rs`, replace the call to `tracing_subscriber` with
Expand Down Expand Up @@ -128,16 +126,16 @@ It will look like this:

We'll come back to this page once we have some trace data generated and sent.

To set up mini-redis, we'll first need to add a few dependencies. Update your
`Cargo.toml` with the following:
To set up mini-redis, we'll first need to add a few dependencies. Add the
following dependencies to your `Cargo.toml` file:

```toml
```bash
# Implements the types defined in the Otel spec
opentelemetry = "0.17.0"
cargo add opentelemetry
# Integration between the tracing crate and the opentelemetry crate
tracing-opentelemetry = "0.17.2"
cargo add tracing-opentelemetry
# Allows you to export data to Jaeger
opentelemetry-jaeger = "0.16.0"
cargo add opentelemetry-jaeger
```

Now, in `src/bin/server.rs`, add the following imports:
Expand Down
6 changes: 3 additions & 3 deletions content/tokio/tutorial/async.md
Original file line number Diff line number Diff line change
Expand Up @@ -499,10 +499,10 @@ implementors, but requires a bunch of unsafe boilerplate code. Instead of using
provided by the [`futures`] crate. This allows us to implement a simple trait to
expose our `Task` struct as a waker.

Add the following dependency to your `Cargo.toml` to pull in `futures`.
Add the `futures` dependency to your `Cargo.toml` file:

```toml
futures = "0.3"
```bash
cargo add futures
```

Then implement [`futures::task::ArcWake`][`ArcWake`].
Expand Down
16 changes: 8 additions & 8 deletions content/tokio/tutorial/hello-tokio.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ then read back the key. This will be done using the Mini-Redis client library.
Let's start by generating a new Rust app:

```bash
$ cargo new my-redis
$ cd my-redis
cargo new my-redis
cd my-redis
```

## Add dependencies

Next, open `Cargo.toml` and add the following right below `[dependencies]`:
Next, add the following dependencies to your `Cargo.toml` file:

```toml
tokio = { version = "1", features = ["full"] }
mini-redis = "0.4"
```bash
cargo add tokio --features full
cargo add mini-redis
```

## Write the code
Expand Down Expand Up @@ -55,13 +55,13 @@ async fn main() -> Result<()> {
Make sure the Mini-Redis server is running. In a separate terminal window, run:

```bash
$ mini-redis-server
mini-redis-server
```

If you have not already installed mini-redis, you can do so with

```bash
$ cargo install mini-redis
cargo install mini-redis
```

Now, run the `my-redis` application:
Expand Down
18 changes: 14 additions & 4 deletions content/tokio/tutorial/shared-state.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ the underlying data. Instead, a `Bytes` instance is a reference-counted handle
to some underlying data. The `Bytes` type is roughly an `Arc<Vec<u8>>` but with
some added capabilities.

To depend on `bytes`, add the following to your `Cargo.toml` in the
`[dependencies]` section:
Add the `bytes` dependency to your `Cargo.toml` file:

```toml
bytes = "1"
```bash
cargo add bytes
```

[`bytes`]: https://docs.rs/bytes/1/bytes/struct.Bytes.html
Expand Down Expand Up @@ -154,6 +153,7 @@ async fn process(socket: TcpStream, db: Db) {
# Holding a `MutexGuard` across an `.await`

You might write code that looks like this:

```rust
use std::sync::{Mutex, MutexGuard};

Expand All @@ -165,8 +165,10 @@ async fn increment_and_do_stuff(mutex: &Mutex<i32>) {
} // lock goes out of scope here
# async fn do_something_async() {}
```

When you try to spawn something that calls this function, you will encounter the
following error message:

```text
error: future cannot be sent between threads safely
--> src/lib.rs:13:5
Expand All @@ -191,11 +193,13 @@ note: future is not `Send` as this value is used across an await
8 | }
| - `mut lock` is later dropped here
```

This happens because the `std::sync::MutexGuard` type is **not** `Send`. This
means that you can't send a mutex lock to another thread, and the error happens
because the Tokio runtime can move a task between threads at every `.await`.
To avoid this, you should restructure your code such that the mutex lock's
destructor runs before the `.await`.

```rust
# use std::sync::{Mutex, MutexGuard};
// This works!
Expand All @@ -209,7 +213,9 @@ async fn increment_and_do_stuff(mutex: &Mutex<i32>) {
}
# async fn do_something_async() {}
```

Note that this does not work:

```rust
use std::sync::{Mutex, MutexGuard};

Expand All @@ -223,6 +229,7 @@ async fn increment_and_do_stuff(mutex: &Mutex<i32>) {
}
# async fn do_something_async() {}
```

This is because the compiler currently calculates whether a future is `Send`
based on scope information only. The compiler will hopefully be updated to
support explicitly dropping it in the future, but for now, you must explicitly
Expand Down Expand Up @@ -250,6 +257,7 @@ We will discuss some approaches to avoid these issues below:

The safest way to handle a mutex is to wrap it in a struct, and lock the mutex
only inside non-async methods on that struct.

```rust
use std::sync::Mutex;

Expand All @@ -270,6 +278,7 @@ async fn increment_and_do_stuff(can_incr: &CanIncrement) {
}
# async fn do_something_async() {}
```

This pattern guarantees that you won't run into the `Send` error, because the
mutex guard does not appear anywhere in an async function. It also protects you
from deadlocks, when using crates whose `MutexGuard` implements `Send`.
Expand All @@ -288,6 +297,7 @@ The [`tokio::sync::Mutex`] type provided by Tokio can also be used. The primary
feature of the Tokio mutex is that it can be held across an `.await` without any
issues. That said, an asynchronous mutex is more expensive than an ordinary
mutex, and it is typically better to use one of the two other approaches.

```rust
use tokio::sync::Mutex; // note! This uses the Tokio mutex

Expand Down

0 comments on commit f730990

Please sign in to comment.