i have this function for my proxy server
async fn main_loop<T>(
mut transport: T,
server_addr: SocketAddr,
early_data: Vec<u8>,
mut middleware: AnalyticsService<IdentityService<MiddlewareError>>,
) -> io::Result<()>
where
T: AsyncRead + AsyncWrite + Unpin,
{
let mut server_stream = TcpStream::connect(server_addr).await?;
server_stream
.write_all(&early_data[..early_data.len()])
.await?;
let mut buf_client = [0u8; 4096];
let mut buf_server = [0u8; 4096];
loop {
futures::select! {
res = transport.read(&mut buf_client).fuse() => {
let len = res?;
if len == 0 {
debug!("Connection Closed");
break;
};
if let Err(e) = middleware.call(&buf_client[..len]).await {
debug!("Error in middleware: {:?}", e);
transport.close().await?;
break;
}
server_stream.write_all(&buf_client[..len]).await?;
},
res = server_stream.read(&mut buf_server).fuse() => {
let len = res?;
if len == 0 {
debug!("Connection Closed");
transport.close().await?;
break;
};
transport.write_all(&buf_server[..len]).await?;
},
}
}
Ok(())
}
but i want to make it such that its easy for me to add more middleware to the stack, but whenever i do
async fn main_loop<T>(
mut transport: T,
server_addr: SocketAddr,
early_data: Vec<u8>,
mut middleware: impl Service<&[u8], Error=MiddlewareError>,
) ...
suddnly i get the following errors:
error[E0502]: cannot borrow buf_client
as mutable because it is also borrowed as immutable
--> src/controller/mod.rs:126:34
|
112 | mut middleware: impl Service<&[u8], Error = MiddlewareError>,
| -------------- lifetime '1
appears in the type of middleware
...
126 | res = transport.read(&mut buf_client).fuse() => {
| ^^^^^^^^^^^^^^^ mutable borrow occurs here
...
133 | if let Err(e) = middleware.call(&buf_client[..len]).await {
| -----------------------------------
| | |
| | immutable borrow occurs here
| argument requires that buf_client
is borrowed for '1
error[E0597]: buf_client
does not live long enough
--> src/controller/mod.rs:133:50
|
112 | mut middleware: impl Service<&[u8], Error = MiddlewareError>,
| -------------- lifetime '1
appears in the type of middleware
...
121 | let mut buf_client = [0u8; 4096];
| -------------- binding buf_client
declared here
...
133 | if let Err(e) = middleware.call(&buf_client[..len]).await {
| -----------------^^^^^^^^^^--------
| | |
| | borrowed value does not live long enough
| argument requires that buf_client
is borrowed for '1
...
154 | }
| - buf_client
dropped here while still borrowed
Some errors have detailed explanations: E0502, E0597.
For more information about an error, try rustc --explain E0502
.
warning: fluxgate
(lib) generated 2 warnings
error: could not compile fluxgate
(lib) due to 2 previous errors; 2 warnings emitted
as if the middleware borrows buf_client for 'static, why is that?
AnalyticsService implements Service<'a [u8]>
and the service trait looks like so
pub trait Service<Request> {
/// The type of the response produced by the service.
type Response;
/// The type of the error that may occur during request processing.
type Error;
/// Processes the given request asynchronously.
///
/// # Arguments
/// * `req` - The request to be processed.
///
/// # Returns
/// A future that resolves to a result containing either the response or an error.
fn call(
&mut self,
req: Request,
) -> impl std::future::Future<Output = Result<Self::Response, Self::Error>> + Send;
}
might this be some problem with async traits? or something deeper i dont understand?
i assume when doing impl Trait<&[u8]>
the lifetime is the entire function and since the buffer is created within it, it gets dropped b4 the lifetime ends