pub type FutureResponse = Box<Future<Item = Response, Error = Error>>;
This expands to pub type FutureResponse = Box<Future<Item = Response, Error = Error> + 'static>; (note the 'static lifetime) because that's the default trait object bound.
That will associate the same lifetime on the response trait object as &self. Whether this will work or not will depend on how the rest of the code is setup.
type Future = Box<Future<Item = Self::Response, Error = Self::Error>>;
Yeah, same issue here except there's no lifetime param to associate with the Box. At this point, I'd say it'll be easier if you put your state that you want to use across futures into an Rc and move clones of it around the futures. I think hyper will ultimately require a static lifetime anyway for the service.
I ended up using Arc and it worked beautifully. But i've run into similar problems, i understand the error. Not sure how to fix it.
fn call(&self, req: Request) -> Self::Future {
if let Some(routeMatch) = self.matchRoute(req.path(), req.method()) {
let mut request: ArcRequest = req.into();
request.paramsMap.insert(routeMatch.params);
let modifiedRequest = match self.middleware {
Some(ref middleware) => {
return box middleware.call(request)
.and_then(|req| routeMatch.handler.call(req, ArcResponse::new()))
.map(|res| res.into())
},
None => request
};
let responseFuture = routeMatch.handler.call(modifiedRequest, ArcResponse::new());
return box responseFuture.map(|res| res.into());
}
// TODO: this should be handled by a user defined 404 handler
return box Ok(
Response::new().with_status(StatusCode::NotFound)
).into_future()
}
I get that, the closure might outlive the self reference because futures have a 'static lifetime, a solution would be to somehow tell the compiler that self will live as long as the boxed future i'm returning (dunno if this is possible?)
The way you express that is fn call<'a>(&'a self, ...) -> Box<Future<...> + 'a>. However, given that youβll need a 'static future eventually, this wonβt work because your self wonβt be static.
The typical way to allow yourself to call methods from future chains expressed as combinators is to make SelfClone and then move a clone of self into the closure. To make Self cloneable, stick its guts into an Arc/Rc or you can wrap just the pieces you want to access from futures into Arc/Rc.