1use processmanager::*;
14use std::sync::Arc;
15use std::time::Duration;
16use tokio::time::{interval, sleep};
17
18struct Worker {
20 id: usize,
21 guard: Arc<RuntimeGuard>,
22}
23
24impl Worker {
25 fn new(id: usize) -> Self {
26 Self {
27 id,
28 guard: Arc::new(RuntimeGuard::default()),
29 }
30 }
31}
32
33impl Runnable for Worker {
34 fn process_start(&self) -> ProcFuture<'_> {
35 let id = self.id;
36 let guard = self.guard.clone();
37
38 Box::pin(async move {
39 let ticker = guard.runtime_ticker().await;
40 let mut tic = interval(Duration::from_secs(1));
41
42 loop {
43 match ticker.tick(tic.tick()).await {
44 ProcessOperation::Next(_) => {
45 println!("worker-{id}: heartbeat");
46 }
47 ProcessOperation::Control(RuntimeControlMessage::Reload) => {
48 println!("worker-{id}: received *reload*");
49 }
50 ProcessOperation::Control(RuntimeControlMessage::Shutdown) => {
51 println!("worker-{id}: shutting down");
52 break;
53 }
54 ProcessOperation::Control(_) => continue,
56 }
57 }
58 Ok(())
59 })
60 }
61
62 fn process_handle(&self) -> Arc<dyn ProcessControlHandler> {
63 self.guard.handle()
64 }
65}
66
67#[tokio::main]
68async fn main() {
69 let manager = ProcessManagerBuilder::default()
73 .pre_insert(Worker::new(0))
74 .pre_insert(Worker::new(1))
75 .build();
76
77 let handle = manager.process_handle();
78
79 tokio::spawn(async move {
81 manager
82 .process_start()
83 .await
84 .expect("manager encountered an error");
85 });
86
87 println!("==> main: sleeping 3 s");
91 sleep(Duration::from_secs(3)).await;
92
93 println!("==> main: initiating graceful shutdown");
97 handle.shutdown().await;
98
99 sleep(Duration::from_secs(1)).await;
101}