aboutsummaryrefslogtreecommitdiff
path: root/src/log.rs
blob: 50a1895e3f91ea4883dccfba1686d57cf9f0d4e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use crate::{mail::send_mail, Config, Status, STATUS};
use std::{
    collections::{BTreeMap, VecDeque},
    sync::Arc,
};
use tokio::sync::RwLock;

static LAST_STATUS: RwLock<BTreeMap<usize, bool>> = RwLock::const_new(BTreeMap::new());
pub static LOG: RwLock<VecDeque<Event>> = RwLock::const_new(VecDeque::new());

pub struct Event {
    pub service: usize,
    pub check: usize,
    pub status: Status,
}

pub async fn update_service(
    config: Arc<Config>,
    service: usize,
    check: usize,
    status: Status,
) -> anyhow::Result<()> {
    let mut last_status = LAST_STATUS.write().await;
    let last_status = last_status.entry(service).or_insert(true);
    let current_status = {
        let status = STATUS.read().await;
        !status
            .range((service, usize::MIN)..(service, usize::MAX))
            .any(|(_, v)| v.status.is_err())
    };

    if *last_status != current_status {
        *last_status = current_status;
        let mut log = LOG.write().await;
        log.push_front(Event {
            status: status.clone(),
            service,
            check,
        });
        while log.len() > 32 {
            log.pop_back();
        }
        if let Err(error) = status.status {
            send_mail(&config, service, check, error).await?;
        }
    }
    Ok(())
}