]>
Commit | Line | Data |
---|---|---|
7a630df7 DM |
1 | use failure::*; |
2 | use lazy_static::lazy_static; | |
3 | use std::sync::Mutex; | |
4 | ||
5 | use futures::*; | |
7a630df7 | 6 | |
b30415d2 | 7 | use tokio_net::signal::unix::{signal, SignalKind}; |
7a630df7 | 8 | |
e45afdff | 9 | use crate::tools::{self, BroadcastData}; |
7a630df7 DM |
10 | |
11 | #[derive(PartialEq, Copy, Clone, Debug)] | |
12 | pub enum ServerMode { | |
13 | Normal, | |
14 | Shutdown, | |
15 | } | |
16 | ||
17 | pub struct ServerState { | |
18 | pub mode: ServerMode, | |
e45afdff DM |
19 | pub shutdown_listeners: BroadcastData<()>, |
20 | pub last_worker_listeners: BroadcastData<()>, | |
7a630df7 DM |
21 | pub worker_count: usize, |
22 | pub reload_request: bool, | |
23 | } | |
24 | ||
7a630df7 DM |
25 | lazy_static! { |
26 | static ref SERVER_STATE: Mutex<ServerState> = Mutex::new(ServerState { | |
27 | mode: ServerMode::Normal, | |
e45afdff DM |
28 | shutdown_listeners: BroadcastData::new(), |
29 | last_worker_listeners: BroadcastData::new(), | |
7a630df7 DM |
30 | worker_count: 0, |
31 | reload_request: false, | |
32 | }); | |
33 | } | |
34 | ||
35 | pub fn server_state_init() -> Result<(), Error> { | |
36 | ||
b30415d2 | 37 | let stream = signal(SignalKind::interrupt())?; |
7a630df7 DM |
38 | |
39 | let future = stream.for_each(|_| { | |
40 | println!("got shutdown request (SIGINT)"); | |
41 | SERVER_STATE.lock().unwrap().reload_request = false; | |
42 | tools::request_shutdown(); | |
aa4110cc WB |
43 | futures::future::ready(()) |
44 | }); | |
7a630df7 DM |
45 | |
46 | let abort_future = last_worker_future().map_err(|_| {}); | |
aa4110cc | 47 | let task = futures::future::select(future, abort_future); |
7a630df7 | 48 | |
aa4110cc | 49 | tokio::spawn(task.map(|_| ())); |
7a630df7 | 50 | |
b30415d2 | 51 | let stream = signal(SignalKind::hangup())?; |
7a630df7 DM |
52 | |
53 | let future = stream.for_each(|_| { | |
54 | println!("got reload request (SIGHUP)"); | |
55 | SERVER_STATE.lock().unwrap().reload_request = true; | |
56 | tools::request_shutdown(); | |
aa4110cc WB |
57 | futures::future::ready(()) |
58 | }); | |
7a630df7 DM |
59 | |
60 | let abort_future = last_worker_future().map_err(|_| {}); | |
aa4110cc | 61 | let task = futures::future::select(future, abort_future); |
7a630df7 | 62 | |
aa4110cc | 63 | tokio::spawn(task.map(|_| ())); |
7a630df7 DM |
64 | |
65 | Ok(()) | |
66 | } | |
67 | ||
68 | pub fn is_reload_request() -> bool { | |
69 | let data = SERVER_STATE.lock().unwrap(); | |
70 | ||
62ee2eb4 | 71 | data.mode == ServerMode::Shutdown && data.reload_request |
7a630df7 DM |
72 | } |
73 | ||
74 | pub fn server_shutdown() { | |
75 | let mut data = SERVER_STATE.lock().unwrap(); | |
76 | ||
77 | println!("SET SHUTDOWN MODE"); | |
78 | ||
79 | data.mode = ServerMode::Shutdown; | |
80 | ||
e45afdff | 81 | data.shutdown_listeners.notify_listeners(Ok(())); |
7a630df7 DM |
82 | |
83 | drop(data); // unlock | |
84 | ||
85 | check_last_worker(); | |
86 | } | |
87 | ||
aa4110cc | 88 | pub fn shutdown_future() -> impl Future<Output = ()> { |
7a630df7 | 89 | let mut data = SERVER_STATE.lock().unwrap(); |
aa4110cc WB |
90 | data |
91 | .shutdown_listeners | |
92 | .listen() | |
93 | .map(|_| ()) | |
7a630df7 DM |
94 | } |
95 | ||
aa4110cc | 96 | pub fn last_worker_future() -> impl Future<Output = Result<(), Error>> { |
7a630df7 | 97 | let mut data = SERVER_STATE.lock().unwrap(); |
e45afdff | 98 | data.last_worker_listeners.listen() |
7a630df7 DM |
99 | } |
100 | ||
101 | pub fn set_worker_count(count: usize) { | |
102 | let mut data = SERVER_STATE.lock().unwrap(); | |
103 | data.worker_count = count; | |
104 | ||
105 | if !(data.mode == ServerMode::Shutdown && data.worker_count == 0) { return; } | |
106 | ||
e45afdff | 107 | data.last_worker_listeners.notify_listeners(Ok(())); |
7a630df7 DM |
108 | } |
109 | ||
110 | ||
111 | pub fn check_last_worker() { | |
112 | ||
113 | let mut data = SERVER_STATE.lock().unwrap(); | |
114 | ||
115 | if !(data.mode == ServerMode::Shutdown && data.worker_count == 0) { return; } | |
116 | ||
e45afdff | 117 | data.last_worker_listeners.notify_listeners(Ok(())); |
7a630df7 | 118 | } |