]> git.proxmox.com Git - proxmox-backup.git/blame - src/server/state.rs
src/bin/proxmox-backup-client.rs: implement task stop
[proxmox-backup.git] / src / server / state.rs
CommitLineData
7a630df7
DM
1use failure::*;
2use lazy_static::lazy_static;
3use std::sync::Mutex;
4
5use futures::*;
7a630df7 6
b30415d2 7use tokio_net::signal::unix::{signal, SignalKind};
7a630df7 8
e45afdff 9use crate::tools::{self, BroadcastData};
7a630df7
DM
10
11#[derive(PartialEq, Copy, Clone, Debug)]
12pub enum ServerMode {
13 Normal,
14 Shutdown,
15}
16
17pub 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
25lazy_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
35pub 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
68pub 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
74pub 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 88pub 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 96pub 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
101pub 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
111pub 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}