8.1 KiB
Трейт Clone для структуры состояния AppState в Axum необходим для обеспечения потокобезопасного (thread-safe) доступа к общим данным, таким как пул соединений с базой данных, из нескольких одновременно обрабатываемых запросов.temofeev+1
Когда вы запускаете веб-сервер на Axum, он обычно работает в многопоточной среде для обработки нескольких запросов параллельно. Каждому запросу (или, точнее, каждому рабочему потоку, который его обрабатывает) требуется свой собственный экземпляр состояния для работы.rust-lang
Подробное объяснение
-
Расшаривание состояния между потоками: Axum использует экстрактор
Stateдля внедрения состояния приложения в обработчики (handlers). Чтобы передать это состояние в разные потоки, которые обрабатывают запросы, Axum должен иметь возможность создавать копии этого состояния. ТрейтCloneпредоставляет стандартизированный способ для такого копирования.docs+1 -
Эффективность клонирования
PgPool: В вашем примере полеdb_poolимеет типPgPoolиз библиотекиsqlx. Важно понимать, что вызов.clone()дляPgPool— это очень дешевая операция. Она не создает новый пул соединений и не открывает новые подключения к базе данных. Вместо этого она создает новый указатель на тот же самый, уже существующий внутренний пул, увеличивая счетчик ссылок (reference counter). Это позволяет безопасно и эффективно использовать один и тот же пул соединений в разных частях вашего приложения одновременно.reddit+1 -
Внутренняя работа Axum с
Arc: Зачастую, если тип состояния реализуетClone, метод.with_state()в Axum неявно оборачивает ваше состояние вArc(Atomic Reference Counted pointer).Arc— это умный указатель, который позволяет безопасно владеть данными из нескольких потоков. КлонированиеArcтакже является дешевой операцией, так как оно лишь увеличивает атомарный счетчик ссылок, не копируя сами данные.leapcell+2
Практические подходы
Существует два основных способа управления состоянием в Axum, которые достигают одной и той же цели:
| Подход | Пример кода | Объяснение |
|---|---|---|
#[derive(Clone)] на структуре (как в вашем примере) |
#[derive(Clone)] struct AppState { db_pool: PgPool } .with_state(state) |
Это самый простой и распространенный способ. Он работает, потому что PgPool и другие подобные "умные" типы уже реализуют Clone эффективно (через Arc внутри) temofeev+1. |
Явное использование Arc |
type AppState = Arc<MyState>; struct MyState { ... } .with_state(Arc::new(my_state)) |
Этот подход делает разделяемое владение более явным в коде. Вы вручную оборачиваете состояние в Arc, а затем клонируете Arc при передаче в .with_state() compile7+1. Результат тот же, но код более многословен. |
Таким образом, требование Clone — это не о дорогостоящем копировании данных, а о механизме безопасного и эффективного разделения доступа к общему состоянию в асинхронной многопоточной среде Axum. Ваш код с #[derive(Clone)] является идиоматичным и правильным для работы с PgPool в Axum.compile7+1
- https://users.rust-lang.org/t/axum-state-when-using-clone-and-arc/114349
- https://docs.rs/axum/latest/axum/extract/struct.State.html
- https://www.reddit.com/r/rust/comments/173zzbb/axum_use_state_without_clone/
- https://snix.dev/rustdoc/axum/extract/struct.State.html
- https://leapcell.io/blog/robust-state-management-in-actix-web-and-axum-applications
- https://temofeev.ru/info/articles/nachalo-raboty-s-axum-samym-populyarnym-veb-freymvorkom-rust/
- https://compile7.org/implement-data-structures/how-to-implement-stack-in-axum/
- https://www.test.guide-it.ru/docs/axum/state-middleware/state.html
- https://www.shuttle.dev/blog/2023/12/06/using-axum-rust
- https://habr.com/ru/articles/770332/
- https://github.com/tokio-rs/axum/issues/1374
- https://github.com/tokio-rs/axum/discussions/2508
- https://stackoverflow.com/questions/78855741/is-it-ok-to-clone-a-connection-pool-in-rust-axum
- https://www.reddit.com/r/rust/comments/16kono9/trying_to_use_mutable_appstate_in_axum_and/
- https://docs.rs/axum/latest/axum/
- https://users.rust-lang.org/t/how-to-pass-app-state-in-axum/104458
- https://qna.habr.com/q/1382956
- https://rust-classes.com/chapter_7_4
- https://www.youtube.com/watch?v=XZtlD_m59sM
- https://tg-rs.github.io/carapax/axum/extract/struct.State.html