I have a tricky lifetime problem that I can't quite wrap my head around. I'm trying to start an actix server with an sql connection from outside (shared between two servers). Somehow, I can't pass the connection in due to lifetime problems. Here's a minimal example:
use actix_rt::net::TcpStream;
use actix_service::fn_service;
type SqlPool = sqlx::Pool<sqlx::sqlite::Sqlite>;
struct SomeState {
pool: SqlPool,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let sql_pool = sqlx::sqlite::SqlitePool::connect("sqlite://users.db").await?;
actix_server::Server::build().bind("ldap", ("0.0.0.0", 12345), move || {
let sql_pool2 = sql_pool.clone();
fn_service(move |_stream: TcpStream| async {
// do something with the stream.
let _state = SomeState {
pool: sql_pool2.clone(),
};
if true {
Err(())
} else {
Ok(())
}
})
})?;
Ok(())
}
AFAIU, the lambda in "bind" has static lifetime, so it should outlive whatever's inside, so it should be okay (but it isn't). The error I get:
error: lifetime may not live long enough
--> examples/actix.rs:15:46
|
15 | fn_service(move |_stream: TcpStream| async {
| ____________________-------------------------_^
| | | |
| | | return type of closure `impl Future` contains a lifetime `'2`
| | lifetime `'1` represents this closure's body
16 | | // do something with the stream.
17 | | let _state = SomeState {
18 | | pool: sql_pool2.clone(),
... |
24 | | }
25 | | })
| |_________^ returning this value requires that `'1` must outlive `'2`
|
= note: closure implements `Fn`, so references to captured variables can't escape the closure
I also tried to make it work with Rc, but I got the same errors. adding/removing move s in the lambda doesn't help, you get different errors of a similar nature.
The question is similar to Trouble with lifetimes in actix-web middleware - #6 by vitalyd, but as recommended there I pass everything by value/clone.