atagen

roundabout

public
Star0
Watch0
052a1a49371c39019ad2acebf23b58977d2fa829
1
ssh://brewery@pls.lobotomise.me:33/atagen/roundabout.git
src/proto.rsRust115 lines2.5 KB
1
use std::{
2
    io::{self, BufRead, BufReader, Write},
3
    os::unix::net::UnixStream,
4
    path::PathBuf,
5
};
6
7
use serde::{Deserialize, Serialize, de::DeserializeOwned};
8
9
use crate::{
10
    sched::{Need, Reason},
11
    units::{Bytes, Dur},
12
};
13
14
pub type LeaseId = u64;
15
16
#[derive(Clone, Debug, Serialize, Deserialize)]
17
pub struct Acquire {
18
    pub need: Need,
19
    pub cwd: PathBuf,
20
    pub cmd: Vec<String>,
21
    pub session: Option<String>,
22
    pub deadline: Option<Dur>,
23
}
24
25
#[derive(Debug, Serialize, Deserialize)]
26
#[serde(tag = "op", rename_all = "snake_case")]
27
pub enum Request {
28
    Acquire(Acquire),
29
    Started { pid: i32 },
30
    Usage { rss: Bytes },
31
    Done,
32
    Status,
33
    Kill { lease: LeaseId },
34
    Extend { lease: LeaseId, by: Dur },
35
    Watch { lease: LeaseId },
36
    Overdue { session: String },
37
}
38
39
#[derive(Clone, Debug, Serialize, Deserialize)]
40
pub struct LeaseInfo {
41
    pub id: LeaseId,
42
    pub cmd: Vec<String>,
43
    pub cwd: PathBuf,
44
    pub session: Option<String>,
45
    pub need: Need,
46
    pub heavy: bool,
47
    pub running: bool,
48
    /// seconds since queued or started, whichever it's doing
49
    pub elapsed: u64,
50
    pub rss: Bytes,
51
    pub overdue: bool,
52
    pub waiting: Option<Reason>,
53
    pub position: usize,
54
}
55
56
#[derive(Debug, Serialize, Deserialize)]
57
pub struct Status {
58
    pub leases: Vec<LeaseInfo>,
59
    pub ram_free: Bytes,
60
    pub ram_budget: Bytes,
61
    pub cores_free: u32,
62
    pub cores: u32,
63
}
64
65
#[derive(Debug, Serialize, Deserialize)]
66
#[serde(tag = "ev", rename_all = "snake_case")]
67
pub enum Event {
68
    Queued {
69
        lease: LeaseId,
70
        position: usize,
71
        reason: Option<Reason>,
72
    },
73
    Granted {
74
        lease: LeaseId,
75
        cores: u32,
76
        heavy: bool,
77
    },
78
    Kill,
79
    Status(Status),
80
    Overdue {
81
        leases: Vec<LeaseInfo>,
82
    },
83
    Fired {
84
        overdue: bool,
85
    },
86
    Ok,
87
    Err {
88
        msg: String,
89
    },
90
}
91
92
pub fn send<T: Serialize>(stream: &mut UnixStream, msg: &T) -> io::Result<()> {
93
    let mut line = serde_json::to_vec(msg)?;
94
    line.push(b'\n');
95
    stream.write_all(&line)
96
}
97
98
pub struct Reader(BufReader<UnixStream>);
99
100
impl Reader {
101
    pub fn new(stream: &UnixStream) -> io::Result<Self> {
102
        Ok(Self(BufReader::new(stream.try_clone()?)))
103
    }
104
105
    /// `Ok(None)` on eof
106
    pub fn recv<T: DeserializeOwned>(&mut self) -> io::Result<Option<T>> {
107
        let mut line = String::new();
108
        if self.0.read_line(&mut line)? == 0 {
109
            return Ok(None);
110
        }
111
        serde_json::from_str(&line)
112
            .map(Some)
113
            .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
114
    }
115
}