handle ctrlc

This commit is contained in:
2025-11-28 20:24:26 -05:00
parent 7557507f27
commit 4aa22de61b
3 changed files with 36 additions and 22 deletions

View File

@@ -43,13 +43,6 @@ impl NetState {
} }
} }
pub fn connection(&self) -> Option<&NetHandle> {
match self {
NetState::Connected(net_handle) => Some(net_handle),
_ => None,
}
}
pub fn take(&mut self) -> Self { pub fn take(&mut self) -> Self {
std::mem::replace(self, Self::None) std::mem::replace(self, Self::None)
} }
@@ -65,7 +58,6 @@ pub fn connect(handle: AppHandle, info: ConnectInfo) -> JoinHandle<()> {
type NetResult<T> = Result<T, String>; type NetResult<T> = Result<T, String>;
type MsgPayload = ClientMsg;
#[derive(Clone)] #[derive(Clone)]
pub struct NetSender { pub struct NetSender {
send: UnboundedSender<NetCtrlMsg>, send: UnboundedSender<NetCtrlMsg>,
@@ -175,7 +167,7 @@ async fn connect_the(handle: AppHandle, info: ConnectInfo) -> NetResult<()> {
} }
} }
NetCtrlMsg::Exit => { NetCtrlMsg::Exit => {
conn.close(quinn::VarInt::from_u32(0), &[]); conn.close(0u32.into(), &[]);
endpoint.wait_idle().await; endpoint.wait_idle().await;
break; break;
} }

View File

@@ -17,7 +17,7 @@ use std::{
atomic::{AtomicU64, Ordering}, atomic::{AtomicU64, Ordering},
}, },
}; };
use tokio::sync::RwLock; use tokio::{signal::ctrl_c, sync::RwLock};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
@@ -42,9 +42,18 @@ pub async fn run_server(port: u16) {
msgs: db.open_tree("msgs").unwrap(), msgs: db.open_tree("msgs").unwrap(),
senders: Default::default(), senders: Default::default(),
count: 0.into(), count: 0.into(),
db, db: db.clone(),
}; };
listen(port, path, handler).await; let (endpoint, handle) = listen(port, path, handler);
let _ = ctrl_c().await;
println!("stopping server");
println!("closing connections...");
endpoint.close(0u32.into(), &[]);
let _ = handle.await;
endpoint.wait_idle().await;
println!("saving...");
db.flush_async().await.unwrap();
println!("saved");
} }
type ClientId = u64; type ClientId = u64;

View File

@@ -10,6 +10,7 @@ use std::{
net::{Ipv6Addr, SocketAddr, SocketAddrV6}, net::{Ipv6Addr, SocketAddr, SocketAddrV6},
sync::Arc, sync::Arc,
}; };
use tokio::task::JoinHandle;
use tracing::Instrument; use tracing::Instrument;
pub const SERVER_HOST: Ipv6Addr = Ipv6Addr::UNSPECIFIED; pub const SERVER_HOST: Ipv6Addr = Ipv6Addr::UNSPECIFIED;
@@ -73,19 +74,31 @@ pub trait ConAccepter: Send + Sync + 'static {
) -> impl Future<Output = impl RecvHandler<ClientMsg>> + Send; ) -> impl Future<Output = impl RecvHandler<ClientMsg>> + Send;
} }
pub async fn listen(port: u16, data_path: &Path, accepter: impl ConAccepter) { pub fn listen(
port: u16,
data_path: &Path,
accepter: impl ConAccepter,
) -> (Endpoint, JoinHandle<()>) {
let accepter = Arc::new(accepter); let accepter = Arc::new(accepter);
let endpoint = init_endpoint(port, data_path); let endpoint = init_endpoint(port, data_path);
println!("listening on {}", endpoint.local_addr().unwrap()); let res = endpoint.clone();
let handle = tokio::spawn(async move {
println!("listening on {}", endpoint.local_addr().unwrap());
let mut tasks = Vec::new();
while let Some(conn) = endpoint.accept().await { while let Some(conn) = endpoint.accept().await {
let fut = handle_connection(conn, accepter.clone()); let fut = handle_connection(conn, accepter.clone());
tokio::spawn(async move { tasks.push(tokio::spawn(async move {
if let Err(e) = fut.await { if let Err(e) = fut.await {
eprintln!("connection failed: {reason}", reason = e) eprintln!("connection failed: {reason}", reason = e)
} }
}); }));
} }
for task in tasks {
let _ = task.await;
}
});
(res, handle)
} }
async fn handle_connection( async fn handle_connection(