I want to use my struct method in hyper .14 service struct impl, to simplify access to request data by a struct instead of passing them to functions, in Hyper doc stated that : "Trait hyper::service::Service as An asynchronous function from a Request to a Response. The Service trait is a simplified interface making it easy to write network applications in a modular and reusable way, decoupled from the underlying protocol. It is one of Tower’s fundamental abstractions." but when I want to use async method of my struct in hyper service struct impl return this error:
error: lifetime may not live long enough
--> examples/service_struct_impl.rs:36:9
|
35 | fn call(&mut self, req: Request<Body>) -> Self::Future {
| - let's call the lifetime of this reference `'1`
36 | Box::pin(self.start_process(req))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
This is my code:
use hyper::service::Service;
use hyper::{Body, Request, Response, Server};
use hyper::StatusCode;
use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
type Counter = i32;
type GenericError = Box<dyn std::error::Error + Send + Sync + 'static>;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = ([127, 0, 0, 1], 3000).into();
let server = Server::bind(&addr).serve(MakeSvc { counter: 81818 });
println!("Listening on http://{}", addr);
server.await?;
Ok(())
}
struct Svc {
counter: Counter,
}
impl Service<Request<Body>> for Svc {
type Response = Response<Body>;
type Error = GenericError;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: Request<Body>) -> Self::Future {
Box::pin(self.start_process(req))
}
}
impl Svc {
async fn start_process(
&mut self,
req: Request<Body>
) -> Result<Response<Body>, GenericError> {
Ok(Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from(format!("Counter is: {}", self.counter)))?)
}
}
struct MakeSvc {
counter: Counter,
}
impl<T> Service<T> for MakeSvc {
type Response = Svc;
type Error = GenericError;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
fn poll_ready(&mut self, _: &mut Context) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, _: T) -> Self::Future {
let counter = self.counter.clone();
let fut = async move { Ok(Svc { counter }) };
Box::pin(fut)
}
}
The future returned from
Service::call()
cannot borrow fromself
.You can, for example,
clone()
the counter incall()
and move it to the async closure: