| 1 | use log::{error, info}; |
| 2 | use std::sync::Arc; |
| 3 | use tokio::signal::unix::{SignalKind, signal}; |
| 4 | use tokio::sync::Mutex; |
| 5 | use tokio::sync::mpsc; |
| 6 | use tokio::sync::mpsc::{Receiver, Sender}; |
| 7 | |
| 8 | async fn shutdown_signal(mut rx: Receiver<String>) { |
| 9 | // перехватчик сигнала SIGTERM |
| 10 | let _terminate = signal(SignalKind::terminate()) |
| 11 | .expect("failed to install signal handler") // если не удалось поставить handler |
| 12 | .recv() // ожидаем следующий сигнал |
| 13 | .await; // await |
| 14 | |
| 15 | println!("SIGTERM received!"); |
| 16 | |
| 17 | match rx.recv().await { |
| 18 | Some(x) => { |
| 19 | println!("gotcha!"); |
| 20 | println!("string from thread: {}", x) |
| 21 | } |
| 22 | None => (), |
| 23 | } |
| 24 | std::process::exit(0); // Graceful exit |
| 25 | } |
| 26 | |
| 27 | async fn test_fx(tx: Arc<Mutex<Option<Sender<String>>>>) { |
| 28 | let tx = tx.lock().await.as_ref().cloned().unwrap(); |
| 29 | |
| 30 | let mut s = 0; |
| 31 | |
| 32 | for i in 1..100 { |
| 33 | // some hard work |
| 34 | s += i; |
| 35 | tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; |
| 36 | } |
| 37 | |
| 38 | let _res = tx.send(format!("-> {}", s)).await; |
| 39 | } |
| 40 | |
| 41 | #[tokio::main] |
| 42 | async fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 43 | println!("Hello, world!"); |
| 44 | |
| 45 | let (tx, mut rx) = mpsc::channel::<String>(1); |
| 46 | let shared_tx = Arc::new(Mutex::new(Some(tx))); |
| 47 | |
| 48 | tokio::spawn(async move { |
| 49 | shutdown_signal(rx).await; |
| 50 | }); |
| 51 | |
| 52 | println!("test"); |
| 53 | |
| 54 | let tx = shared_tx.clone(); |
| 55 | tokio::spawn(async move { test_fx(tx).await }); |
| 56 | |
| 57 | println!("test2"); |
| 58 | |
| 59 | loop { |
| 60 | tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; |
| 61 | }; |
| 62 | |
| 63 | } |
aquafire / async-signal_handler.rs
Last active 6 months ago