I'm using seanmonstar/warp to build my rest service and faced the problem related to lifetimes. Here is how my application starting code looks like:
struct MyModelStruct {
//...
}
struct Database {
//...
}
impl Database {
fn connect(/* ommited */) -> Database {
//...
}
}
fn start_app(db: &Database) -> () {
let route = warp::post()
.and(warp::path!("action" / u32))
.and(warp::body::json::<MyModelSctruct>())
.map(|_, _| {
//use db
})
warp::serve(route).run(/* address */);
}
I got the error:
error[E0621]: explicit lifetime required in the type of `db`
--> src/application.rs:69:5
|
46 | fn start_app(db: &Database) -> (){
| -------- help: add explicit lifetime `'static` to the type of `db`: `&'static db::Database`
...
69 | warp::serve(route);
| ^^^^^^^^^^^ lifetime `'static` required
This is because the warp::serve
function is defined as
/// Create a `Server` with the provided `Filter`.
pub fn serve<F>(filter: F) -> Server<F>
where
F: Filter + Clone + Send + Sync + 'static,
F::Extract: Reply,
F::Error: IsReject,
{
Server {
pipeline: false,
filter,
}
}
So the 'static
lifetime is required explicitly. The problem is it is used as
let db = Database::connect(...);
start_app(&db);
So the lifetime of db is not static
. Is there a way to workaround this?
A 'static
lifetime means that the function is guaranteed to not reference any data that could be dropped before the function itself is dropped. Because you are currently passing in a &Database
, your function cannot be 'static
(unless you were somehow passing a &'static Database
, which would require explicitly creating a memory leak).
The only way around this would be for you to either pass Database
or Arc<Database>
or something along that would allow access so that the function has a strong reference to the Database
and can guarantee that the DB will continue to exist as long as the function does.