feat: Move some PDU commands to !admin rooms graph

This commit is contained in:
timedout committed 2026-10-31 22:56:13 +00:00
1 parent 5de3d74436
commit b651fbd088
3 files changed
+103 -169

No files matched your search

+2 -137
View File
@@ -7,10 +7,7 @@ use std::{
use conduwuit::{
Err, Result, debug_error, err, info,
matrix::{
Event,
pdu::{PduEvent, PduId, RawPduId},
},
matrix::{Event, pdu::PduEvent},
trace, utils,
utils::{
stream::{IterStream, ReadyExt},
@@ -28,10 +25,7 @@ use ruma::{
CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName,
RoomId, RoomVersionId, UInt, api::federation::event::get_room_state,
};
use service::rooms::{
short::{ShortEventId, ShortRoomId},
state_compressor::HashSetCompressStateEvent,
};
use service::rooms::state_compressor::HashSetCompressStateEvent;
use tracing_subscriber::EnvFilter;
use crate::PAGE_SIZE;
@@ -300,79 +294,6 @@ impl crate::Context<'_> {
.await
}
pub(super) async fn get_pdu(&self, event_id: OwnedEventId) -> Result {
let mut outlier = false;
let mut pdu_json = self
.services
.rooms
.timeline
.get_non_outlier_pdu_json(&event_id)
.await;
if pdu_json.is_err() {
outlier = true;
pdu_json = self.services.rooms.timeline.get_pdu_json(&event_id).await;
}
let rejected = self
.services
.rooms
.pdu_metadata
.is_event_rejected(&event_id)
.await;
let soft_failed = self
.services
.rooms
.pdu_metadata
.is_event_soft_failed(&event_id)
.await;
match pdu_json {
| Err(_) => return Err!("PDU not found locally."),
| Ok(json) => {
let text = serde_json::to_string_pretty(&json)?;
let msg = if rejected {
"Rejected PDU:"
} else if soft_failed {
"Soft-failed PDU:"
} else if outlier {
"Outlier PDU:"
} else {
"PDU:"
};
write!(self, "{msg}\n```json\n{text}\n```")
},
}
.await
}
pub(super) async fn get_short_pdu(
&self,
shortroomid: ShortRoomId,
shorteventid: ShortEventId,
) -> Result {
let pdu_id: RawPduId = PduId {
shortroomid,
shorteventid: shorteventid.into(),
}
.into();
let pdu_json = self
.services
.rooms
.timeline
.get_pdu_json_from_id(&pdu_id)
.await;
match pdu_json {
| Err(_) => return Err!("PDU not found locally."),
| Ok(json) => {
let json_text = serde_json::to_string_pretty(&json)?;
write!(self, "```json\n{json_text}\n```")
},
}
.await
}
pub(super) async fn get_remote_pdu_list(
&self,
server: OwnedServerName,
@@ -624,62 +545,6 @@ impl crate::Context<'_> {
self.write_str(msg).await
}
#[tracing::instrument(skip(self), level = "info")]
pub(super) async fn first_pdu_in_room(&self, room_id: OwnedRoomId) -> Result {
self.bail_restricted()?;
if !self
.services
.rooms
.state_cache
.server_in_room(&self.services.server.name, &room_id)
.await
{
return Err!(
"We are not participating in the room / we don't know about the room ID.",
);
}
let first_pdu = self
.services
.rooms
.timeline
.first_pdu_in_room(&room_id)
.await
.map_err(|_| err!(Database("Failed to find the first PDU in database")))?;
let out = format!("{first_pdu:?}");
self.write_str(&out).await
}
#[tracing::instrument(skip(self), level = "info")]
pub(super) async fn latest_pdu_in_room(&self, room_id: OwnedRoomId) -> Result {
self.bail_restricted()?;
if !self
.services
.rooms
.state_cache
.server_in_room(&self.services.server.name, &room_id)
.await
{
return Err!(
"We are not participating in the room / we don't know about the room ID."
);
}
let latest_pdu = self
.services
.rooms
.timeline
.latest_pdu_in_room(&room_id)
.await
.map_err(|_| err!(Database("Failed to find the latest PDU in database")))?;
let out = format!("{latest_pdu:?}");
self.write_str(&out).await
}
#[tracing::instrument(skip(self), level = "info")]
pub(super) async fn force_set_room_state_from_server(
&self,
-30
View File
@@ -4,7 +4,6 @@ pub(crate) mod tester;
use clap::Subcommand;
use conduwuit::Result;
use ruma::{OwnedEventId, OwnedRoomId, OwnedServerName};
use service::rooms::short::{ShortEventId, ShortRoomId};
use self::tester::TesterCommand;
use crate::admin_command_dispatch;
@@ -41,21 +40,6 @@ pub enum DebugCommand {
/// the command.
ParsePdu,
/// Retrieve and print a PDU by EventID from the Continuwuity database
GetPdu {
/// An event ID (a $ followed by the base64 reference hash)
event_id: OwnedEventId,
},
/// Retrieve and print a PDU by PduId from the Continuwuity database
GetShortPdu {
/// Shortroomid integer
shortroomid: ShortRoomId,
/// Shorteventid integer
shorteventid: ShortEventId,
},
/// Attempts to retrieve a PDU from a remote server. **Does not** insert
/// it into the database
/// or persist it anywhere.
@@ -109,20 +93,6 @@ pub enum DebugCommand {
event_id: OwnedEventId,
},
/// Prints the very first PDU in the specified room (typically
/// m.room.create)
FirstPduInRoom {
/// The room ID
room_id: OwnedRoomId,
},
/// Prints the latest ("last") PDU in the specified room (typically a
/// message)
LatestPduInRoom {
/// The room ID
room_id: OwnedRoomId,
},
/// Forcefully replaces the room state of our local copy of the specified
/// room, with the copy (auth chain and room state events) the specified
/// remote server says.
+101 -2
View File
@@ -1,8 +1,8 @@
use clap::Subcommand;
use conduwuit::{Err, Event, Result, utils::stream::BroadbandExt};
use conduwuit::{Err, Event, Result, err, utils::stream::BroadbandExt};
use conduwuit_macros::admin_command_dispatch;
use futures::StreamExt;
use ruma::OwnedRoomOrAliasId;
use ruma::{OwnedEventId, OwnedRoomId, OwnedRoomOrAliasId};
#[admin_command_dispatch]
#[derive(Debug, Subcommand)]
@@ -11,6 +11,26 @@ pub enum GraphCommand {
ListExtremities {
room: OwnedRoomOrAliasId,
},
/// Fetches a PDU (event) by its event ID, as stored in the database. Also
/// includes details about the PDU state.
GetPDU {
event_id: OwnedEventId,
},
/// Yields the first PDU we became aware of in a room.
/// This is always the room's create event for local rooms, or the first
/// membership event that introduced us to the remote room.
#[clap(name = "first-pdu")]
FirstPduInRoom {
room_id: OwnedRoomId,
},
/// Yields the most recent PDU in a room.
#[clap(name = "latest-pdu")]
LatestPduInRoom {
room_id: OwnedRoomId,
},
}
impl crate::Context<'_> {
@@ -54,4 +74,83 @@ impl crate::Context<'_> {
Ok(())
}
pub(super) async fn get_pdu(&self, event_id: OwnedEventId) -> Result {
let mut outlier = false;
let mut pdu_json = self
.services
.rooms
.timeline
.get_non_outlier_pdu_json(&event_id)
.await;
if pdu_json.is_err() {
outlier = true;
pdu_json = self.services.rooms.timeline.get_pdu_json(&event_id).await;
}
let rejected = self
.services
.rooms
.pdu_metadata
.is_event_rejected(&event_id)
.await;
let soft_failed = self
.services
.rooms
.pdu_metadata
.is_event_soft_failed(&event_id)
.await;
match pdu_json {
| Err(_) => return Err!("PDU not found locally."),
| Ok(json) => {
let text = serde_json::to_string_pretty(&json)?;
let msg = if rejected {
"Rejected PDU:"
} else if soft_failed {
"Soft-failed PDU:"
} else if outlier {
"Outlier PDU:"
} else {
"Timeline PDU:"
};
write!(self, "{msg}\n```json\n{text}\n```")
},
}
.await
}
pub(super) async fn first_pdu_in_room(&self, room_id: OwnedRoomId) -> Result {
self.bail_restricted()?;
let first_pdu = self
.services
.rooms
.timeline
.first_pdu_in_room(&room_id)
.await
.map(Event::into_canonical_object)
.and_then(|v| serde_json::to_string_pretty(&v).map_err(Into::into))
.map_err(|e| err!(Database("Failed to find the first PDU in database: {e:?}")))?;
let out = format!("```json\n{first_pdu}\n```");
self.write_str(&out).await
}
pub(super) async fn latest_pdu_in_room(&self, room_id: OwnedRoomId) -> Result {
self.bail_restricted()?;
let latest_pdu = self
.services
.rooms
.timeline
.latest_pdu_in_room(&room_id)
.await
.map(Event::into_canonical_object)
.and_then(|v| serde_json::to_string_pretty(&v).map_err(Into::into))
.map_err(|e| err!(Database("Failed to find the latest PDU in database: {e:?}")))?;
let out = format!("```json\n{latest_pdu}\n```");
self.write_str(&out).await
}
}