Использование состояния приложения с параметром времени жизни, вызывающим проблему с временем жизни в компиляторе ржавчины - PullRequest
1 голос
/ 21 марта 2020

Я определил состояние приложения для параметра времени жизни, как показано ниже:

pub struct ServiceState<'a> {
    pub db: sync::Mutex<Database<'a>>,
}

impl<'a> ServiceState<'a> {
    pub async fn new() -> Result<ServiceState<'a>, Error> {
        let db = database::ConnectionPool::new(CONFIGURATION).await?;
        Ok(ServiceState {
            db: sync::Mutex::new(db),
        })
    }
}

, и передал его на сервер actix, как ожидается, с кодом ниже:

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    let state = model::ServiceState::new();
    let uri = connection::uri();
    let data = web::Data::new(state);
    let mut server = HttpServer::new(move || {
        App::new()
            .app_data(data.clone())
            .configure(routes::configuration)
    });

    // ... more code ...

    server.run().await
}

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

pub async fn do_stuff(
    state: web::Data<model::ServiceState<'_>>,
    json: web::Json<model::RequestBody>,
) -> HttpResponse {
    let _data = model::RequestBody::from(json);

    // MutexGuard<'_, Database<'_>> is just to show what types are being used

    let db: MutexGuard<'_, Database<'_>> = state.db.lock().unwrap();
    let _client = db.client().await.unwrap();

    // ... would be other logic here but commented out to isolate error

    HttpResponse::Ok().finish()
}

Я получаю следующие ошибки:

error[E0597]: `state` does not live long enough
  --> src/handler/verification.rs:12:48
   |
8  |     state: web::Data<model::ServiceState<'_>>,
   |     ----- lifetime `'1` appears in the type of `state`
...
12 |     let mut db: MutexGuard<'_, Database<'_>> = state.db.lock().unwrap();
   |                                                ^^^^^----------
   |                                                |
   |                                                borrowed value does not live long enough
   |                                                argument requires that `state` is borrowed for `'1`
...
32 | }
   | - `state` dropped here while still borrowed

error[E0597]: `db` does not live long enough
  --> src/handler/verification.rs:13:19
   |
8  |     state: web::Data<model::ServiceState<'_>>,
   |     ----- lifetime `'1` appears in the type of `state`
...
13 |     let _client = db.client().await.unwrap();
   |                   ^^---------
   |                   |
   |                   borrowed value does not live long enough
   |                   argument requires that `db` is borrowed for `'1`
...
32 | }
   | - `db` dropped here while still borrowed

Я выкалывал и подталкивал это для в то время как, экспериментируя с разными временами жизни, указывая, что один должен жить дольше, чем другой, et c безрезультатно. Я думаю, что мне не хватает конкретного понимания того, почему происходит это сообщение об ошибке. Мой мыслительный процесс - и клиент, и БД - заимствованы внутри функции, поэтому я не понимаю, почему может возникнуть проблема, что они отбрасываются после завершения функции.

Я отмечу, что мой код (больше чем в этом примере) все работало нормально, пока я не ввел параметр времени жизни в состояние приложения, поэтому я предполагаю, что я просто не предоставляю некоторые параметры времени жизни, которые ранее не использовался компилятором.

Надеюсь, текущего примера достаточно для по крайней мере, получить некоторое представление о том, что происходит не так.

Любая помощь будет принята с благодарностью, я довольно плохо знаком с rust / actix и изо всех сил пытаюсь получить это (то, что, похоже, должно быть довольно распространенным и простым вариантом использования) на работу.

...