Я пишу свою первую службу Rust REST и у меня есть несколько вопросов о том, как правильно реализовать потокобезопасность.
Я следую этому руководству и хотел бы сосредоточиться на шаге где они показывают, как выполнить POST.
Они настраивают структуру Store
, которая происходит от Clone
и выглядит так:
#[derive(Clone)]
struct Store {
grocery_list: Arc<RwLock<Items>>
}
В main
они настраивают Warp likeo:
async fn main() {
let store = Store::new();
let store_filter = warp::any().map(move || store.clone());
let add_items = warp::post()
// ..... Non important path stuff
.and(store_filter.clone())
.and_then(add_grocery_list_item);
// More non-important stuff
}
Мой вопрос: можно ли, чтобы Store
не происходил от Clone
, просто оберните его в Arc
и вместо этого клонируйте Arc
и просто иметь Store
внутреннее беспокойство о безопасности потоков, используя RwLock
?
Это то, что я думаю о магазине:
struct Store {
grocery_list: RwLock<Items>
}
И настройка Warp:
async fn main() {
let store_arc = Arc<Store>::new(Store::new());
let store_arc_filter = warp::any().map(move || store_arc.clone());
let add_items = warp::post()
// ..... Non important path stuff
.and(store_arc_filter.clone())
.and_then(add_grocery_list_item);
// More non-important stuff
}
Я что-нибудь нарушаю, делая это?
Если я правильно понимаю, исходный экземпляр Arc
принадлежит закрытию, которое принадлежит store_filter
. Каждый раз, когда поступает запрос, Arc
клонируется замыканием и передается в потоке, выполняющем запрос. Когда запрос завершается и поток перезапускается, Arc
очищается. В глобальном масштабе всегда существует один экземпляр Store
, общий для всех созданных Arc
клонов.
Правильно ли я понимаю, как все это работает?