Handle TcpListener.accept errors more gracefully

This commit is contained in:
Brian Picciano 2024-02-29 10:48:53 +01:00
parent c76d7318f0
commit fcc8b860fc
2 changed files with 21 additions and 9 deletions

View File

@ -6,6 +6,7 @@ pub use config::*;
use crate::error::unexpected::{self, Mappable}; use crate::error::unexpected::{self, Mappable};
use crate::{domain, service, task_stack, util}; use crate::{domain, service, task_stack, util};
use core::time::Duration;
use std::sync; use std::sync;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
@ -248,8 +249,15 @@ async fn listen(
loop { loop {
let (conn, addr) = tokio::select! { let (conn, addr) = tokio::select! {
res = listener.accept() => res.or_unexpected_while("accepting connection")?, res = listener.accept() => {
_ = canceller.cancelled() => return Ok(()), if let Err(err) = res {
log::error!("Failed to accept new gemini request on {addr}: {err}");
tokio::time::sleep(Duration::from_secs(2)).await;
continue;
}
res.unwrap()
},
_ = canceller.cancelled() => return Ok(()),
}; };
let service = service.clone(); let service = service.clone();

View File

@ -1,8 +1,9 @@
use crate::error::unexpected::{self, Intoable, Mappable}; use crate::error::unexpected::{self, Mappable};
use crate::service; use crate::service;
use std::{net, pin, sync}; use std::{net, pin, sync};
use core::time::Duration;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
async fn serve_conn<Conn>( async fn serve_conn<Conn>(
@ -21,7 +22,6 @@ async fn serve_conn<Conn>(
req_is_https, req_is_https,
); );
use core::time::Duration;
use hyper_util::{ use hyper_util::{
rt::tokio::{TokioExecutor, TokioIo, TokioTimer}, rt::tokio::{TokioExecutor, TokioIo, TokioTimer},
server::conn::auto::Builder, server::conn::auto::Builder,
@ -95,8 +95,10 @@ pub async fn listen_http(
worker.done() worker.done()
}); });
}, },
Err(err) => Err(err) => {
return Err(err.into_unexpected_while(format!("accepting new HTTP requests on {addr}"))), log::error!("Failed to accept new HTTP request on {addr}: {err}");
tokio::time::sleep(Duration::from_secs(2)).await;
},
} }
}, },
_ = canceller.cancelled() => { _ = canceller.cancelled() => {
@ -144,7 +146,7 @@ pub async fn listen_https(
let stream = match server_config.accept(raw_stream).await { let stream = match server_config.accept(raw_stream).await {
Ok(s) => s, Ok(s) => s,
Err(err) => { Err(err) => {
log::warn!("failed to accept TLS connection on {addr}: {err}"); log::warn!("Failed to accept TLS connection on {addr}: {err}");
worker.done(); worker.done();
return; return;
} }
@ -154,8 +156,10 @@ pub async fn listen_https(
worker.done(); worker.done();
}); });
}, },
Err(err) => Err(err) => {
return Err(err.into_unexpected_while(format!("accepting new HTTPS requests on {addr}"))), log::error!("Failed to accept new HTTPS request on {addr}: {err}");
tokio::time::sleep(Duration::from_secs(2)).await;
},
} }
}, },
_ = canceller.cancelled() => { _ = canceller.cancelled() => {