use crate::shutdown::Shutdown;
use log::info;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
pub struct Service {
control: Shutdown,
}
impl Service {
pub fn new(control: Shutdown) -> Self {
Self { control }
}
pub async fn serve(&mut self) -> Option<()> {
info!("SERVICE: RUN");
let communication_loop = tokio::spawn(async move {
let listener = TcpListener::bind("127.0.0.1:8080").await.ok()?;
loop {
// Wait for incoming network request.
// Dispatch it to the communicator and repeat.
// This is ECHO server example from the Tokio dokumentation.
let (mut socket, _) = listener.accept().await.ok()?;
tokio::spawn(async move {
let mut buf = [0; 1024];
// In a loop, read data from the socket and write the data back.
loop {
let n = match socket.read(&mut buf).await {
// socket closed
Ok(n) if n == 0 => return Option::Some(()),
Ok(n) => n,
Err(e) => {
eprintln!("failed to read from socket; err = {:?}", e);
return Option::Some(());
}
};
// Write the data back
if let Err(e) = socket.write_all(&buf[0..n]).await {
eprintln!("failed to write to socket; err = {:?}", e);
return Option::Some(());
}
}
});
}
// TODO: Needs some cleanup as this required by
// compiler but does generate warning.
Option::Some(())
});
self.control.recv().await;
info!("SERVICE: RECEIVED CONTROL SIGNAL");
communication_loop.abort();
info!("COMMUNICATION: CANCELLED");
info!("SERVICE: STOP");
Option::Some(())
}
}