synapse_admin_api/background_updates/status/
v1.rs

1//! [GET /_synapse/admin/v1/background_updates/status](https://github.com/element-hq/synapse/blob/master/docs/usage/administration/admin_api/background_updates.md#status)
2
3use std::collections::HashMap;
4
5use ruma::api::{auth_scheme::AccessToken, metadata, request, response};
6use serde::{Deserialize, Serialize};
7
8metadata! {
9    method: GET,
10    rate_limited: false,
11    authentication: AccessToken,
12    path: "/_synapse/admin/v1/background_updates/status",
13}
14
15#[request]
16#[derive(Default)]
17pub struct Request {}
18
19#[response]
20#[derive(Serialize, Deserialize, PartialEq)]
21pub struct Response {
22    /// Whether the background updates are enabled.
23    pub enabled: bool,
24
25    /// The current update based on database name.
26    pub current_updates: HashMap<String, CurrentUpdate>,
27}
28
29/// Information about a current update.
30///
31/// To create an instance of this type, first create a `CurrentUpdateInit` and convert it via
32/// `CurrentUpdate::from` / `.into()`.
33#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
34#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
35pub struct CurrentUpdate {
36    /// Name of the update.
37    pub name: String,
38
39    /// Total number of processed "items".
40    pub total_item_count: u64,
41
42    /// Runtime of background process, not including sleeping time.
43    pub total_duration_ms: f64,
44
45    /// Items processed per millisecond based on an exponential average.
46    pub average_items_per_ms: f64,
47}
48
49/// Initial set of fields of [`CurrentUpdate`].
50///
51/// This struct will not be updated even if additional fields are added to `CurrentUpdate`.
52#[derive(Debug)]
53#[allow(clippy::exhaustive_structs)]
54pub struct CurrentUpdateInit {
55    /// Name of the update.
56    pub name: String,
57
58    /// Total number of processed "items".
59    pub total_item_count: u64,
60
61    /// Runtime of background process, not including sleeping time.
62    pub total_duration_ms: f64,
63
64    /// Items processed per millisecond based on an exponential average.
65    pub average_items_per_ms: f64,
66}
67
68impl From<CurrentUpdateInit> for CurrentUpdate {
69    fn from(value: CurrentUpdateInit) -> Self {
70        let CurrentUpdateInit { name, total_item_count, total_duration_ms, average_items_per_ms } =
71            value;
72        Self { name, total_item_count, total_duration_ms, average_items_per_ms }
73    }
74}
75
76impl Request {
77    /// Creates an empty `Request`.
78    pub fn new() -> Self {
79        Self {}
80    }
81}
82
83impl Response {
84    /// Creates a `Response` with the given parameters.
85    pub fn new(enabled: bool, current_updates: HashMap<String, CurrentUpdate>) -> Self {
86        Self { enabled, current_updates }
87    }
88}
89
90#[test]
91fn test_status_background_updates() {
92    let name = "current update 1";
93    let total_item_count = 123_456_789;
94    let total_duration_ms = 2_134_567.123_45;
95    let average_items_per_ms = 2.5;
96
97    // Create the current update
98    let update = CurrentUpdate {
99        name: name.to_owned(),
100        total_item_count,
101        total_duration_ms,
102        average_items_per_ms,
103    };
104    assert_eq!(update.name, name);
105    assert_eq!(update.total_item_count, total_item_count);
106    assert_eq!(update.total_duration_ms, total_duration_ms);
107    assert_eq!(update.average_items_per_ms, average_items_per_ms);
108
109    // Create the hashmap
110    let mut current_updates = HashMap::new();
111    current_updates.insert("master".to_owned(), update);
112    let enabled = true;
113
114    let response = Response::new(enabled, current_updates);
115
116    // Serialize
117    let serialized = serde_json::to_string(&response).expect("Failed to serialize");
118    assert_eq!(
119        serialized,
120        "{\"enabled\":true,\"current_updates\":{\"master\":{\"name\":\"current update 1\",\"total_item_count\":123456789,\"total_duration_ms\":2134567.12345,\"average_items_per_ms\":2.5}}}"
121    );
122
123    // Deserialize
124    let deserialized: Response = serde_json::from_str(&serialized).expect("Failed to deserialize");
125    assert_eq!(deserialized, response);
126}