atagen

roundabout

public
Star0
Watch0
4e5ca2e2040139a56cdd8bc50993e0f82ceab09a
1
ssh://brewery@pls.lobotomise.me:33/atagen/roundabout.git
src/proto.rsRust147 lines3.1 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
    #[serde(default)]
24
    pub exact: bool,
25
}
26
27
#[derive(Debug, Serialize, Deserialize)]
28
#[serde(tag = "op", rename_all = "snake_case")]
29
pub enum Request {
30
    /// `None` withdraws it
31
    Expect {
32
        session: String,
33
        need: Option<Need>,
34
    },
35
    Acquire(Acquire),
36
    Started {
37
        pid: i32,
38
    },
39
    Usage {
40
        rss: Bytes,
41
    },
42
    Done,
43
    Status,
44
    Kill {
45
        lease: LeaseId,
46
    },
47
    Extend {
48
        lease: LeaseId,
49
        by: Dur,
50
    },
51
    Watch {
52
        lease: LeaseId,
53
    },
54
    Overdue {
55
        session: String,
56
    },
57
}
58
59
#[derive(Clone, Debug, Serialize, Deserialize)]
60
pub struct LeaseInfo {
61
    pub id: LeaseId,
62
    pub cmd: Vec<String>,
63
    pub cwd: PathBuf,
64
    pub session: Option<String>,
65
    pub need: Need,
66
    pub heavy: bool,
67
    pub running: bool,
68
    #[serde(default)]
69
    pub granted: u32,
70
    /// seconds since queued or started, whichever it's doing
71
    pub elapsed: u64,
72
    pub rss: Bytes,
73
    pub overdue: bool,
74
    pub waiting: Option<Reason>,
75
    pub position: usize,
76
}
77
78
#[derive(Clone, Debug, Serialize, Deserialize)]
79
pub struct IntentInfo {
80
    pub session: String,
81
    pub need: Need,
82
    pub expires_in: u64,
83
}
84
85
#[derive(Debug, Serialize, Deserialize)]
86
pub struct Status {
87
    pub leases: Vec<LeaseInfo>,
88
    pub intents: Vec<IntentInfo>,
89
    pub ram_free: Bytes,
90
    pub ram_budget: Bytes,
91
    pub cores_free: u32,
92
    pub cores: u32,
93
}
94
95
#[derive(Debug, Serialize, Deserialize)]
96
#[serde(tag = "ev", rename_all = "snake_case")]
97
pub enum Event {
98
    Queued {
99
        lease: LeaseId,
100
        position: usize,
101
        reason: Option<Reason>,
102
    },
103
    Granted {
104
        lease: LeaseId,
105
        cores: u32,
106
        /// grows with any bonus cores, since more jobs means more ram
107
        ram: Bytes,
108
        heavy: bool,
109
    },
110
    Kill,
111
    Status(Status),
112
    Overdue {
113
        leases: Vec<LeaseInfo>,
114
    },
115
    Fired {
116
        overdue: bool,
117
    },
118
    Ok,
119
    Err {
120
        msg: String,
121
    },
122
}
123
124
pub fn send<T: Serialize>(stream: &mut UnixStream, msg: &T) -> io::Result<()> {
125
    let mut line = serde_json::to_vec(msg)?;
126
    line.push(b'\n');
127
    stream.write_all(&line)
128
}
129
130
pub struct Reader(BufReader<UnixStream>);
131
132
impl Reader {
133
    pub fn new(stream: &UnixStream) -> io::Result<Self> {
134
        Ok(Self(BufReader::new(stream.try_clone()?)))
135
    }
136
137
    /// `Ok(None)` on eof
138
    pub fn recv<T: DeserializeOwned>(&mut self) -> io::Result<Option<T>> {
139
        let mut line = String::new();
140
        if self.0.read_line(&mut line)? == 0 {
141
            return Ok(None);
142
        }
143
        serde_json::from_str(&line)
144
            .map(Some)
145
            .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
146
    }
147
}