misskey_api/streaming/channel/
server_stats.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Deserialize, Debug, Clone)]
4#[serde(rename_all = "camelCase")]
5pub struct MemStats {
6    pub used: u64,
7    pub active: u64,
8}
9
10#[derive(Deserialize, Debug, Clone)]
11#[serde(rename_all = "camelCase")]
12pub struct NetStats {
13    pub rx: f64,
14    pub tx: f64,
15}
16
17#[derive(Deserialize, Debug, Clone)]
18#[serde(rename_all = "camelCase")]
19pub struct FsStats {
20    pub r: f64,
21    pub w: f64,
22}
23
24#[derive(Deserialize, Debug, Clone)]
25#[serde(rename_all = "camelCase")]
26pub struct ServerStats {
27    pub cpu: f64,
28    pub mem: MemStats,
29    pub net: NetStats,
30    pub fs: FsStats,
31}
32
33#[derive(Deserialize, Debug, Clone)]
34#[serde(rename_all = "camelCase", tag = "type", content = "body")]
35pub enum ServerStatsEvent {
36    Stats(ServerStats),
37    StatsLog(Vec<ServerStats>),
38}
39
40#[derive(Serialize, Debug, Clone)]
41#[serde(rename_all = "camelCase", tag = "type", content = "body")]
42pub enum Message {
43    RequestLog { id: String, length: u64 },
44}
45
46#[derive(Serialize, Default, Debug, Clone)]
47pub struct Request {}
48
49impl misskey_core::streaming::ConnectChannelRequest for Request {
50    type Incoming = ServerStatsEvent;
51    type Outgoing = Message;
52
53    const NAME: &'static str = "serverStats";
54}
55
56#[cfg(test)]
57mod tests {
58    use super::{Message, Request, ServerStatsEvent};
59    use crate::test::websocket::TestClient;
60
61    use futures::{future, SinkExt, StreamExt};
62
63    #[tokio::test]
64    async fn subscribe_unsubscribe() {
65        let client = TestClient::new().await;
66        let mut stream = client.channel(Request::default()).await.unwrap();
67        stream.disconnect().await.unwrap();
68    }
69
70    #[tokio::test]
71    async fn stream_stats() {
72        use std::time::Duration;
73
74        let client = TestClient::new().await;
75        let mut stream = client.channel(Request::default()).await.unwrap();
76
77        // margin of 100 ms
78        tokio::time::timeout(Duration::from_millis(2100), async {
79            loop {
80                match stream.next().await.unwrap().unwrap() {
81                    ServerStatsEvent::Stats(_) => break,
82                    _ => continue,
83                }
84            }
85        })
86        .await
87        .unwrap();
88    }
89
90    #[tokio::test]
91    async fn stream_stats_log() {
92        use ulid_crate::Ulid;
93
94        let client = TestClient::new().await;
95        let (mut sink, mut stream) = client.channel(Request::default()).await.unwrap().split();
96
97        future::join(
98            async {
99                sink.send(Message::RequestLog {
100                    id: Ulid::new().to_string(),
101                    length: 50,
102                })
103                .await
104                .unwrap();
105            },
106            async {
107                loop {
108                    match stream.next().await.unwrap().unwrap() {
109                        ServerStatsEvent::StatsLog(_) => break,
110                        _ => continue,
111                    }
112                }
113            },
114        )
115        .await;
116    }
117}