Ссылки на захваченные переменные на сервере Actix вызывают «аргумент требует, чтобы он пережил« статический » - PullRequest
0 голосов
/ 10 февраля 2019

В приведенном ниже примере у меня есть параметры verbose и data_source, которые задаются параметрами командной строки.verbose - логический флаг, но data_source используется для выбора значения по умолчанию из набора доступных функций, которые могут использоваться в зависимости от источника данных для приложения.

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

Если я правильно понимаю сообщение об ошибке, на самом деле само замыкание не может пережить 'static.

Что я должен сделать, чтобы решить эту проблему?

extern crate actix;
extern crate actix_web;
extern crate env_logger;

use actix_web::http::Method;
use actix_web::{middleware, server, App, HttpRequest, HttpResponse};

enum DataSource {
    Postgres,
    HDF5,
}

fn index_postgres(req: &HttpRequest) -> HttpResponse {
    HttpResponse::Ok().body("not implemented")
}

fn index_hdf5(req: &HttpRequest) -> HttpResponse {
    HttpResponse::Ok().body("not implemented")
}

fn main() {
    let mut verbose = false;
    verbose = true;
    let mut data_source = DataSource::Postgres;
    data_source = DataSource::HDF5;

    let index = match data_source {
        DataSource::Postgres => index_postgres,
        DataSource::HDF5 => index_hdf5,
    };

    ::std::env::set_var("RUST_LOG", "actix_web=info");
    env_logger::init();
    let sys = actix::System::new("test");

    server::new(move || {
        if verbose {
            App::new()
                .middleware(middleware::Logger::default())
                .resource("/", |r| r.method(Method::GET).f(index))
        } else {
            App::new().resource("/", |r| r.method(Method::GET).f(index))
        }
    })
    .bind("127.0.0.1:8080")
    .unwrap()
    .start();

    println!("Started http server: 127.0.0.1:8080");
    let _ = sys.run();
}
error: unsatisfied lifetime constraints
  --> src\main.rs:50:13
   |
48 |       server::new(move || {
   |                   ------- lifetime `'1` represents this closure's body
49 |           if verbose {
50 | /             App::new()
51 | |                 .middleware(middleware::Logger::default())
52 | |                 .resource("/", |r| r.method(Method::GET).f(index))
   | |__________________________________________________________________^ argument requires that `'1` must outlive `'static`
   |
   = note: closure implements `Fn`, so references to captured variables can't escape the closure

1 Ответ

0 голосов
/ 10 февраля 2019

Я не понимаю, что пытается сказать компилятор, но очевидно, что вам нужно move в замыканиях обработчиков:

if verbose {
    App::new()
        .middleware(middleware::Logger::default())
        .resource("/", move |r| r.method(Method::GET).f(index))
} else {
    App::new().resource("/", move |r| r.method(Method::GET).f(index))
}

Это потому, что вам нужно переместить index из внешнего замыкания.

...