Плавная остановка приема в Rust
Долго живущий процесс обычно останавливают по сигналу с клавиатуры или от системы. Резкий выход может оборвать ответ клиенту, который уже ждет данные.
Цикл приема умеет ждать отдельную асинхронную функцию завершения. Пока она не закончится, новые соединения не принимают, а текущие запросы дорабатывают.
Для ожидания сигнала с клавиатуры включите
возможность signal у исполнителя:
cargo add tokio --features signal
Передайте функцию завершения в цикл приема:
use axum::{Router, routing::get};
async fn root() -> &'static str {
"ok"
}
async fn shutdown_signal() {
match tokio::signal::ctrl_c().await {
Ok(()) => {}
Err(e) => eprintln!("{}", e),
}
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(root));
let listener = match tokio::net::TcpListener::bind("127.0.0.1:3000").await {
Ok(l) => l,
Err(e) => {
eprintln!("{}", e);
return;
}
};
match axum::serve(listener, app)
.with_graceful_shutdown(shutdown_signal())
.await
{
Ok(()) => {}
Err(e) => eprintln!("{}", e),
}
}
После нажатия сочетания прерывания цикл перестает принимать новые запросы и закрывается, когда активные обработчики закончат работу.
Перед выходом можно напечатать короткое сообщение внутри функции завершения:
use axum::{Router, routing::get};
async fn root() -> &'static str {
"ok"
}
async fn shutdown_signal() {
match tokio::signal::ctrl_c().await {
Ok(()) => println!("stop"),
Err(e) => eprintln!("{}", e),
}
}
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(root));
let listener = match tokio::net::TcpListener::bind("127.0.0.1:3000").await {
Ok(l) => l,
Err(e) => {
eprintln!("{}", e);
return;
}
};
match axum::serve(listener, app)
.with_graceful_shutdown(shutdown_signal())
.await
{
Ok(()) => {}
Err(e) => eprintln!("{}", e),
}
}
Дан путь:
/
Добавьте плавное завершение к серверу
с этим адресом и выведите bye
при сигнале с клавиатуры.
Скажите, примет ли сервер новый запрос сразу после срабатывания функции завершения, но до конца активных обработчиков.
Опишите, как разобрать сбой цикла приема после завершения через исход операции.