Ржавчина, деформация и безопасность потоков - PullRequest
0 голосов
/ 17 июня 2020

Я пишу свою первую службу 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 клонов.

Правильно ли я понимаю, как все это работает?

...