Передача дополнительного состояния ржавчине `hyper :: service :: service_fn` - PullRequest
0 голосов
/ 02 апреля 2020

У меня проблемы с передачей дополнительного состояния в мою сервисную функцию, но я не могу отсортировать время жизни в замыканиях. Ни один из учебников, кажется, не решает эту проблему:

https://hyper.rs/

https://docs.rs/hyper/0.13.4/hyper/server/index.html

https://docs.rs/hyper/0.13.4/hyper/service/fn.make_service_fn.html

Соответствующий код:

#[tokio::main]                                                                       
async fn main() {                                                               
    let addr = ([127, 0, 0, 1], 8080).into();                                   
    let db = Arc::new(Mutex::new(Slab::new()));                                 
    let server = Server::bind(&addr).serve(make_service_fn(|_conn| async {      
        let db = db.clone();                                                         
        Ok::<_, Infallible>(service_fn(move |req| serve_req(req, &db)))         
    }));                                                                             
    if let Err(e) = server.await {                                                   
        eprintln!("server error: {}", e)                                             
    }                                                                                
}

Ошибки:

   Compiling hyper-microservice v0.1.0 (/data/repos/rust/hyper-microservice)
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
   --> src/main.rs:121:66
    |
121 |         Ok::<_, Infallible>(service_fn(move |req| serve_req(req, &db)))
    |                                                                  ^^^
    |
note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 121:40...
   --> src/main.rs:121:40
    |
121 |         Ok::<_, Infallible>(service_fn(move |req| serve_req(req, &db)))
    |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that closure can access `db`
   --> src/main.rs:121:66
    |
121 |         Ok::<_, Infallible>(service_fn(move |req| serve_req(req, &db)))
    |                                                                  ^^^
note: but, the lifetime must be valid for the expression at 121:29...
   --> src/main.rs:121:29
    |
121 |         Ok::<_, Infallible>(service_fn(move |req| serve_req(req, &db)))
    |                             ^^^^^^^^^^

Насколько я понимаю, make_service_fn отвечает за возврат ServiceFn, который может использоваться для обслуживания запросов для данного соединения, и он создает новый ServiceFn для каждого соединения. Теперь service_fn принимает функцию / замыкание, которое принимает запрос и возвращает Future, который возвращает ответ (или ошибку). И, насколько я понимаю, ServiceFn может выполняться несколько раз за соединение. Таким образом, примерно каждый клиент получает свой собственный поток, который выполняет асинхронную сервисную функцию c для каждого запроса в этом соединении (чтобы один и тот же клиент мог сделать несколько запросов в одном соединении и одновременно обслуживаться в одном потоке).

Я полагаю, что может случиться так, что компилятор считает, что одно из замыканий может пережить дБ?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...