Как изящно отключить среду выполнения Tokio в ответ на SIGTERM?
У меня есть main
функция, где я создаю среду исполнения Tokio и запускаю на ней два фьючерса.
use tokio;
fn main() {
let mut runtime = tokio::runtime::Runtime::new().unwrap();
runtime.spawn(MyMegaFutureNumberOne {});
runtime.spawn(MyMegaFutureNumberTwo {});
// Some code to 'join' them after receiving an OS signal
}
Как я могу получить SIGTERM
Дождись всех незавершенных заданий (NotReady
s) и выйти из приложения?
2 ответа
Работать с сигналами сложно, и было бы слишком сложно объяснить, как обрабатывать все возможные случаи. Реализация сигналов не является стандартной для разных платформ, поэтому мой ответ специфичен для Linux. Если вы хотите быть более кроссплатформенным, используйте функцию POSIX sigaction
в сочетании с pause
; это предложит вам больше контроля.
Один из способов добиться того, чего вы хотите, - использовать ящик tokio_signal для перехвата сигналов, например: (пример документа)
extern crate futures;
extern crate tokio;
extern crate tokio_signal;
use futures::prelude::*;
use futures::Stream;
use std::time::{Duration, Instant};
use tokio_signal::unix::{Signal, SIGINT, SIGTERM};
fn main() -> Result<(), Box<::std::error::Error>> {
let mut runtime = tokio::runtime::Runtime::new()?;
let sigint = Signal::new(SIGINT).flatten_stream();
let sigterm = Signal::new(SIGTERM).flatten_stream();
let stream = sigint.select(sigterm);
let deadline = tokio::timer::Delay::new(Instant::now() + Duration::from_secs(5))
.map(|()| println!("5 seconds are over"))
.map_err(|e| eprintln!("Failed to wait: {}", e));
runtime.spawn(deadline);
let (item, _rest) = runtime
.block_on_all(stream.into_future())
.map_err(|_| "failed to wait for signals")?;
let item = item.ok_or("received no signal")?;
if item == SIGINT {
println!("received SIGINT");
} else {
assert_eq!(item, SIGTERM);
println!("received SIGTERM");
}
Ok(())
}
Эта программа будет ожидать завершения всех текущих задач и перехватит выбранные сигналы. Похоже, что это не работает в Windows, поскольку мгновенно завершает работу программы.
Другой ответ - для Tokio версии 0.1.x, которая очень старая. Для Tokio версии 1.xy в официальном руководстве Tokio есть страница по этой теме: Изящное завершение работы