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