Skip to main content

tuwunel_admin/query/
sync.rs

1use clap::Subcommand;
2use ruma::{OwnedDeviceId, OwnedUserId};
3use tuwunel_core::Result;
4use tuwunel_service::sync::into_connection_key;
5
6use crate::{admin_command, admin_command_dispatch};
7
8#[admin_command_dispatch]
9#[derive(Debug, Subcommand)]
10/// Query sync service state
11pub(crate) enum SyncCommand {
12	/// List sliding-sync connections.
13	ListConnections,
14
15	/// Show details of sliding sync connection by ID.
16	ShowConnection {
17		user_id: OwnedUserId,
18		device_id: Option<OwnedDeviceId>,
19		conn_id: Option<String>,
20	},
21
22	/// Drop connections for a user, device, or all.
23	DropConnections {
24		user_id: Option<OwnedUserId>,
25		device_id: Option<OwnedDeviceId>,
26		conn_id: Option<String>,
27	},
28}
29
30#[admin_command]
31pub(super) async fn list_connections(&self) -> Result {
32	let connections = self.services.sync.list_loaded_connections().await;
33
34	for connection_key in connections {
35		self.write_str(&format!("{connection_key:?}\n"))
36			.await?;
37	}
38
39	Ok(())
40}
41
42#[admin_command]
43pub(super) async fn show_connection(
44	&self,
45	user_id: OwnedUserId,
46	device_id: Option<OwnedDeviceId>,
47	conn_id: Option<String>,
48) -> Result {
49	let key = into_connection_key(user_id, device_id, conn_id);
50	let cache = self
51		.services
52		.sync
53		.get_loaded_connection(&key)
54		.await?;
55
56	let out;
57	{
58		let cached = cache.lock().await;
59		out = format!("{cached:#?}");
60	};
61
62	self.write_str(out.as_str()).await
63}
64
65#[admin_command]
66pub(super) async fn drop_connections(
67	&self,
68	user_id: Option<OwnedUserId>,
69	device_id: Option<OwnedDeviceId>,
70	conn_id: Option<String>,
71) -> Result {
72	self.services
73		.sync
74		.clear_connections(
75			user_id.as_deref(),
76			device_id.as_deref(),
77			conn_id.map(Into::into).as_ref(),
78		)
79		.await;
80
81	Ok(())
82}