#rust-rocket
Вопрос:
В принципе, я хочу, чтобы один процесс обрабатывал несколько вещей одновременно (в частности, я хочу иметь конечную точку http для мониторинга службы, не связанной с http), но, похоже, я попал в ракету в зависимости от времени выполнения tokio для конкретной ракеты, и я не вижу, как это обойти. Я думал о том, чтобы сделать rocket основной точкой входа вместо стандартной tokio и запускать другие вещи из этой среды выполнения, но в целом это кажется неправильным и хрупким, поскольку я мог бы переключать библиотеки. Я думал об использовании hyper и warp, и я несколько уверен, что смогу заставить их работать в этой ситуации, но хочу использовать rocket, как я использую его в другом месте в этом проекте. Я использую версию 0.5-rc01.
Из документов:
Rocket v0.5 uses the tokio runtime. The runtime is started for you if you use #[launch] or #[rocket::main], but you can still launch() a Rocket instance on a custom-built runtime by not using either attribute.
К сожалению, я не могу найти никаких дополнительных объяснений того, какие требования предъявляет эта специально созданная среда выполнения, и никаких примеров, не использующих макросы запуска/main.
Вот упрощенная версия кода, который я пытаюсь использовать:
#[rocket::get("/ex")]
async fn test() -> amp;'static str {
"OK"
}
#[tokio::main]
async fn main() {
tokio::spawn(async {
let config = Config {
port: 8001,
address: std::net::Ipv4Addr::new(127, 0, 0, 1).into(),
..Config::debug_default()
};
rocket::custom(amp;config)
.mount("/", rocket::routes![test])
.launch()
.await;
});
let start = Instant::now();
let mut interval = interval_at(start, tokio::time::Duration::from_secs(5));
loop {
interval.tick().await;
println!("Other scheduled work");
}
}
Когда я нажимаю CTRL-C, чтобы завершить процесс, выводится следующее:
^CWarning: Received SIGINT. Requesting shutdown.
Received shutdown request. Waiting for pending I/O...
Warning: Server failed to shutdown cooperatively.
>> Server is executing inside of a custom runtime.
>> Rocket's runtime is `#[rocket::main]` or `#[launch]`.
>> Refusing to terminate runaway custom runtime.
Other scheduled work
Other scheduled work
Other scheduled work
Я нашел эту документацию, объясняющую, что вам нужно «сотрудничать» при завершении работы, если вы используете пользовательскую среду выполнения, но в ней не объясняется, что влечет за собой сотрудничество. Кроме того, запуск чего-либо, кроме ракеты, в порожденном потоке приводит к тому, что CTRL-C убивает процесс, как я обычно ожидал, поэтому я думаю, что это связано именно с ракетой. Что мне нужно сделать, чтобы я действительно мог убить процесс?
Правка: Я сдался и переключился на варп, что было в тысячу раз проще. Мне все равно было бы любопытно узнать, как правильно сделать это с помощью rocket, и я бы попробовал еще раз, если у кого-нибудь есть предложения.
Ответ №1:
Я думаю, вы могли бы просто позволить Rocket позаботиться о запуске вашего tokio runtime:
#[rocket::main]
async fn main() {
tokio::spawn(async {
let start = Instant::now();
let mut interval = interval_at(start, tokio::time::Duration::from_secs(5));
loop {
interval.tick().await;
println!("Other scheduled work");
}
});
let config = Config {
port: 8001,
address: std::net::Ipv4Addr::new(127, 0, 0, 1).into(),
..Config::debug_default()
};
rocket::custom(amp;config)
.mount("/", rocket::routes![test])
.launch()
.await;
}
Ваша собственная дополнительная логика может быть реализована в задаче, которую вы создаете, и ракета запускается обычным способом.