Skip to content

Commit

Permalink
feat: Add background_updates endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
hanadi92 authored Jan 26, 2024
1 parent 60e6db4 commit 470f06d
Show file tree
Hide file tree
Showing 9 changed files with 234 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Work around a Synapse issue affecting sqlite configurations
* Update v1/server_version endpoint response data with optional python_version key
* Upgrade to ruma 0.9.4
* Add background updates endpoints

# 0.4.0

Expand Down
5 changes: 5 additions & 0 deletions src/background_updates.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! Endpoints in the `/_synapse/admin/v<x>/background_updates/` scope to manage background updates.
pub mod enabled;
pub mod run;
pub mod status;
3 changes: 3 additions & 0 deletions src/background_updates/enabled.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Different versions of the endpoint to trigger background updates enabled status.
pub mod v1;
65 changes: 65 additions & 0 deletions src/background_updates/enabled/v1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//! [POST /_synapse/admin/v1/background_updates/enabled](https://github.com/element-hq/synapse/blob/develop/docs/usage/administration/admin_api/background_updates.md#enabled)
use ruma::{
api::{request, response, Metadata},
metadata,
};
use serde::{Deserialize, Serialize};

const METADATA: Metadata = metadata! {
method: POST,
rate_limited: false,
authentication: AccessToken,
history: {
unstable => "/_synapse/admin/v1/background_updates/enabled",
}
};

#[request]
pub struct Request {
/// Sets whether the background updates are enabled.
pub enabled: bool,
}

#[response]
#[derive(Serialize, Deserialize, PartialEq)]
pub struct Response {
/// Whether the background updates are enabled or disabled.
pub enabled: bool,
}

impl Request {
/// Creates a `Request` with the given `enabled` value.
pub fn new(enabled: bool) -> Self {
Self { enabled }
}
}

impl Response {
/// Creates a `Response` with the given `enabled` value.
pub fn new(enabled: bool) -> Self {
Self { enabled }
}
}

#[test]
fn test_enabled_background_updates() {
let enabled = true;

// Check create request
let request = Request::new(enabled);
assert!(request.enabled);

// Check create response
let response = Response::new(enabled);
assert!(request.enabled);

// Serialize
let serialized = serde_json::to_string(&response).expect("Failed to serialize");
assert_eq!(serialized, "{\"enabled\":true}");

// Deserialize
let deserialized: Response = serde_json::from_str(&serialized).expect("Failed to deserialize");
assert_eq!(deserialized, response);
assert!(deserialized.enabled);
}
3 changes: 3 additions & 0 deletions src/background_updates/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Different versions of the endpoint to start a job in background updates.
pub mod v1;
61 changes: 61 additions & 0 deletions src/background_updates/run/v1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//! [POST /_synapse/admin/v1/background_updates/start_job](https://github.com/element-hq/synapse/blob/master/docs/usage/administration/admin_api/background_updates.md#run)
use ruma::{
api::{request, response, Metadata},
metadata,
serde::StringEnum,
};

const METADATA: Metadata = metadata! {
method: POST,
rate_limited: false,
authentication: AccessToken,
history: {
unstable => "/_synapse/admin/v1/background_updates/start_job",
}
};

#[request]
pub struct Request {
/// Which job to run.
pub job_name: JobName,
}

#[response]
#[derive(Default)]
pub struct Response {}

impl Request {
/// Creates a `Request` with the given `job_name` value.
pub fn new(job_name: JobName) -> Self {
Self { job_name }
}
}

impl Response {
/// Creates an empty `Response`.
pub fn new() -> Self {
Self {}
}
}

#[derive(Clone, PartialEq, StringEnum)]
#[ruma_enum(rename_all = "snake_case")]
pub enum JobName {
/// Recalculate the stats for all rooms.
PopulateStatsProcessRooms,

/// Recalculate the user directory if it is stale or out of sync.
RegenerateDirectory,

#[doc(hidden)]
_Custom(crate::PrivOwnedStr),
}

#[test]
fn test_run_background_updates() {
let job_name = JobName::PopulateStatsProcessRooms;
// Check create request
let request = Request::new(job_name.clone());
assert_eq!(request.job_name, job_name);
}
3 changes: 3 additions & 0 deletions src/background_updates/status.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
//! Different versions of the endpoint to get the current status of the background updates.
pub mod v1;
92 changes: 92 additions & 0 deletions src/background_updates/status/v1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//! [GET /_synapse/admin/v1/background_updates/status](https://github.com/element-hq/synapse/blob/master/docs/usage/administration/admin_api/background_updates.md#status)
use ruma::api::{metadata, request, response, Metadata};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

const METADATA: Metadata = metadata! {
method: GET,
rate_limited: false,
authentication: AccessToken,
history: {
unstable => "/_synapse/admin/v1/background_updates/status",
}
};

#[request]
#[derive(Default)]
pub struct Request {}

#[response]
#[derive(Serialize, Deserialize, PartialEq)]
pub struct Response {
/// Whether the background updates are enabled.
pub enabled: bool,

/// The current update based on database name.
pub current_updates: HashMap<String, CurrentUpdate>,
}

#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
pub struct CurrentUpdate {
/// Name of the update.
pub name: String,

/// Total number of processed "items".
pub total_item_count: u64,

/// Runtime of background process, not including sleeping time.
pub total_duration_ms: f64,

/// Items processed per millisecond based on an exponential average.
pub average_items_per_ms: f64,
}

impl Request {
/// Creates an empty `Request`.
pub fn new() -> Self {
Self {}
}
}

impl Response {
/// Creates a `Response` with the given parameters.
pub fn new(enabled: bool, current_updates: HashMap<String, CurrentUpdate>) -> Self {
Self { enabled, current_updates }
}
}

#[test]
fn test_status_background_updates() {
let name = "current update 1".to_string();
let total_item_count = 123456789;
let total_duration_ms = 2134567.12345;
let average_items_per_ms = 2.5;

// Create the current update
let update = CurrentUpdate {
name: name.clone(),
total_item_count,
total_duration_ms,
average_items_per_ms,
};
assert_eq!(update.name, name);
assert_eq!(update.total_item_count, total_item_count);
assert_eq!(update.total_duration_ms, total_duration_ms);
assert_eq!(update.average_items_per_ms, average_items_per_ms);

// Create the hashmap
let mut current_updates = HashMap::new();
current_updates.insert("master".to_string(), update);
let enabled = true;

let response = Response::new(enabled, current_updates);

// Serialize
let serialized = serde_json::to_string(&response).expect("Failed to serialize");
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}}}");

// Deserialize
let deserialized: Response = serde_json::from_str(&serialized).expect("Failed to deserialize");
assert_eq!(deserialized, response);
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use std::fmt;

pub mod account_validity;
pub mod background_updates;
pub mod register_users;
pub mod rooms;
pub mod users;
Expand Down

0 comments on commit 470f06d

Please sign in to comment.