2025-04-29 06:39:30 +00:00
|
|
|
mod append;
|
|
|
|
|
mod backfill;
|
|
|
|
|
mod build;
|
|
|
|
|
mod create;
|
2024-05-26 21:29:19 +00:00
|
|
|
mod data;
|
2025-04-29 06:39:30 +00:00
|
|
|
mod redact;
|
2022-10-05 20:41:05 +02:00
|
|
|
|
2025-04-29 06:39:30 +00:00
|
|
|
use std::{fmt::Write, sync::Arc};
|
2022-09-06 23:15:09 +02:00
|
|
|
|
2025-03-15 04:07:53 +00:00
|
|
|
use async_trait::async_trait;
|
2025-04-29 06:39:30 +00:00
|
|
|
pub use conduwuit_core::matrix::pdu::{PduId, RawPduId};
|
|
|
|
|
use conduwuit_core::{
|
|
|
|
|
Result, Server, at, err,
|
2025-04-04 03:30:13 +00:00
|
|
|
matrix::{
|
2025-04-29 06:39:30 +00:00
|
|
|
event::Event,
|
|
|
|
|
pdu::{PduCount, PduEvent},
|
2025-01-04 04:12:50 +00:00
|
|
|
},
|
2025-04-29 06:39:30 +00:00
|
|
|
utils::{MutexMap, MutexMapGuard, future::TryExtExt, stream::TryIgnore},
|
|
|
|
|
warn,
|
2024-12-15 00:05:47 -05:00
|
|
|
};
|
2025-04-29 06:39:30 +00:00
|
|
|
use futures::{Future, Stream, TryStreamExt, pin_mut};
|
2022-10-05 20:34:31 +02:00
|
|
|
use ruma::{
|
2025-06-03 21:31:02 +01:00
|
|
|
CanonicalJsonObject, EventId, OwnedEventId, OwnedRoomId, RoomId,
|
2025-04-29 06:39:30 +00:00
|
|
|
events::room::encrypted::Relation,
|
2022-10-05 20:34:31 +02:00
|
|
|
};
|
2022-09-06 23:15:09 +02:00
|
|
|
use serde::Deserialize;
|
2020-05-03 17:25:31 +02:00
|
|
|
|
2024-07-18 06:37:47 +00:00
|
|
|
use self::data::Data;
|
2025-12-13 21:36:20 +00:00
|
|
|
pub use self::{create::pdu_fits, data::PdusIterItem};
|
2022-10-05 20:34:31 +02:00
|
|
|
use crate::{
|
2025-04-29 06:39:30 +00:00
|
|
|
Dep, account_data, admin, appservice, globals, pusher, rooms, sending, server_keys, users,
|
2022-10-05 20:34:31 +02:00
|
|
|
};
|
2022-09-07 13:25:51 +02:00
|
|
|
|
2024-03-08 11:48:52 -05:00
|
|
|
// Update Relationships
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
|
struct ExtractRelatesTo {
|
|
|
|
|
#[serde(rename = "m.relates_to")]
|
|
|
|
|
relates_to: Relation,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
|
|
|
struct ExtractEventId {
|
|
|
|
|
event_id: OwnedEventId,
|
|
|
|
|
}
|
|
|
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
|
|
|
struct ExtractRelatesToEventId {
|
|
|
|
|
#[serde(rename = "m.relates_to")]
|
|
|
|
|
relates_to: ExtractEventId,
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-12 00:33:12 -04:00
|
|
|
#[derive(Deserialize)]
|
|
|
|
|
struct ExtractBody {
|
|
|
|
|
body: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-09 15:59:08 -07:00
|
|
|
pub struct Service {
|
2024-07-18 06:37:47 +00:00
|
|
|
services: Services,
|
2024-06-28 22:51:39 +00:00
|
|
|
db: Data,
|
2024-07-09 21:10:14 +00:00
|
|
|
pub mutex_insert: RoomMutexMap,
|
2022-08-07 19:42:22 +02:00
|
|
|
}
|
|
|
|
|
|
2024-07-18 06:37:47 +00:00
|
|
|
struct Services {
|
|
|
|
|
server: Arc<Server>,
|
|
|
|
|
account_data: Dep<account_data::Service>,
|
|
|
|
|
appservice: Dep<appservice::Service>,
|
|
|
|
|
admin: Dep<admin::Service>,
|
|
|
|
|
alias: Dep<rooms::alias::Service>,
|
|
|
|
|
globals: Dep<globals::Service>,
|
|
|
|
|
short: Dep<rooms::short::Service>,
|
|
|
|
|
state: Dep<rooms::state::Service>,
|
|
|
|
|
state_cache: Dep<rooms::state_cache::Service>,
|
|
|
|
|
state_accessor: Dep<rooms::state_accessor::Service>,
|
|
|
|
|
pdu_metadata: Dep<rooms::pdu_metadata::Service>,
|
|
|
|
|
read_receipt: Dep<rooms::read_receipt::Service>,
|
|
|
|
|
sending: Dep<sending::Service>,
|
2024-07-31 21:05:15 +00:00
|
|
|
server_keys: Dep<server_keys::Service>,
|
2024-07-18 06:37:47 +00:00
|
|
|
user: Dep<rooms::user::Service>,
|
2024-10-02 00:56:09 -04:00
|
|
|
users: Dep<users::Service>,
|
2024-07-18 06:37:47 +00:00
|
|
|
pusher: Dep<pusher::Service>,
|
|
|
|
|
threads: Dep<rooms::threads::Service>,
|
|
|
|
|
search: Dep<rooms::search::Service>,
|
|
|
|
|
event_handler: Dep<rooms::event_handler::Service>,
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-09 21:10:14 +00:00
|
|
|
type RoomMutexMap = MutexMap<OwnedRoomId, ()>;
|
|
|
|
|
pub type RoomMutexGuard = MutexMapGuard<OwnedRoomId, ()>;
|
|
|
|
|
|
2025-03-15 04:07:53 +00:00
|
|
|
#[async_trait]
|
2024-07-04 03:26:19 +00:00
|
|
|
impl crate::Service for Service {
|
|
|
|
|
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
|
|
|
|
Ok(Arc::new(Self {
|
2024-07-18 06:37:47 +00:00
|
|
|
services: Services {
|
|
|
|
|
server: args.server.clone(),
|
|
|
|
|
account_data: args.depend::<account_data::Service>("account_data"),
|
|
|
|
|
appservice: args.depend::<appservice::Service>("appservice"),
|
|
|
|
|
admin: args.depend::<admin::Service>("admin"),
|
|
|
|
|
alias: args.depend::<rooms::alias::Service>("rooms::alias"),
|
|
|
|
|
globals: args.depend::<globals::Service>("globals"),
|
|
|
|
|
short: args.depend::<rooms::short::Service>("rooms::short"),
|
|
|
|
|
state: args.depend::<rooms::state::Service>("rooms::state"),
|
|
|
|
|
state_cache: args.depend::<rooms::state_cache::Service>("rooms::state_cache"),
|
2024-12-15 00:05:47 -05:00
|
|
|
state_accessor: args
|
|
|
|
|
.depend::<rooms::state_accessor::Service>("rooms::state_accessor"),
|
2024-07-18 06:37:47 +00:00
|
|
|
pdu_metadata: args.depend::<rooms::pdu_metadata::Service>("rooms::pdu_metadata"),
|
|
|
|
|
read_receipt: args.depend::<rooms::read_receipt::Service>("rooms::read_receipt"),
|
|
|
|
|
sending: args.depend::<sending::Service>("sending"),
|
2024-07-31 21:05:15 +00:00
|
|
|
server_keys: args.depend::<server_keys::Service>("server_keys"),
|
2024-07-18 06:37:47 +00:00
|
|
|
user: args.depend::<rooms::user::Service>("rooms::user"),
|
2024-10-02 00:56:09 -04:00
|
|
|
users: args.depend::<users::Service>("users"),
|
2024-07-18 06:37:47 +00:00
|
|
|
pusher: args.depend::<pusher::Service>("pusher"),
|
|
|
|
|
threads: args.depend::<rooms::threads::Service>("rooms::threads"),
|
|
|
|
|
search: args.depend::<rooms::search::Service>("rooms::search"),
|
2024-12-15 00:05:47 -05:00
|
|
|
event_handler: args
|
|
|
|
|
.depend::<rooms::event_handler::Service>("rooms::event_handler"),
|
2024-07-18 06:37:47 +00:00
|
|
|
},
|
|
|
|
|
db: Data::new(&args),
|
2024-07-09 21:10:14 +00:00
|
|
|
mutex_insert: RoomMutexMap::new(),
|
2024-07-04 03:26:19 +00:00
|
|
|
}))
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-15 04:07:53 +00:00
|
|
|
async fn memory_usage(&self, out: &mut (dyn Write + Send)) -> Result {
|
2024-07-09 21:22:44 +00:00
|
|
|
let mutex_insert = self.mutex_insert.len();
|
|
|
|
|
writeln!(out, "insert_mutex: {mutex_insert}")?;
|
|
|
|
|
|
2024-07-04 03:26:19 +00:00
|
|
|
Ok(())
|
2024-05-27 03:17:20 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-04 03:26:19 +00:00
|
|
|
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Service {
|
2024-07-07 19:03:15 +00:00
|
|
|
#[tracing::instrument(skip(self), level = "debug")]
|
2025-04-27 02:39:28 +00:00
|
|
|
pub async fn first_pdu_in_room(&self, room_id: &RoomId) -> Result<impl Event> {
|
2025-01-04 04:12:50 +00:00
|
|
|
self.first_item_in_room(room_id).await.map(at!(1))
|
2021-08-09 19:15:14 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2024-07-07 19:03:15 +00:00
|
|
|
#[tracing::instrument(skip(self), level = "debug")]
|
2025-04-27 02:39:28 +00:00
|
|
|
pub async fn first_item_in_room(&self, room_id: &RoomId) -> Result<(PduCount, impl Event)> {
|
2025-06-03 21:31:02 +01:00
|
|
|
let pdus = self.pdus(room_id, None);
|
2025-01-04 04:12:50 +00:00
|
|
|
|
|
|
|
|
pin_mut!(pdus);
|
|
|
|
|
pdus.try_next()
|
2024-08-08 17:18:30 +00:00
|
|
|
.await?
|
|
|
|
|
.ok_or_else(|| err!(Request(NotFound("No PDU found in room"))))
|
2024-05-30 23:36:48 -04:00
|
|
|
}
|
|
|
|
|
|
2025-01-04 04:12:50 +00:00
|
|
|
#[tracing::instrument(skip(self), level = "debug")]
|
2025-04-27 02:39:28 +00:00
|
|
|
pub async fn latest_pdu_in_room(&self, room_id: &RoomId) -> Result<impl Event> {
|
2025-06-03 21:31:02 +01:00
|
|
|
self.db.latest_pdu_in_room(room_id).await
|
2025-01-04 04:12:50 +00:00
|
|
|
}
|
|
|
|
|
|
2024-07-07 19:03:15 +00:00
|
|
|
#[tracing::instrument(skip(self), level = "debug")]
|
2025-06-03 21:31:02 +01:00
|
|
|
pub async fn last_timeline_count(&self, room_id: &RoomId) -> Result<PduCount> {
|
|
|
|
|
self.db.last_timeline_count(room_id).await
|
2022-06-19 22:56:14 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2023-02-20 22:59:45 +01:00
|
|
|
/// Returns the `count` of this pdu's id.
|
2024-12-15 00:05:47 -05:00
|
|
|
pub async fn get_pdu_count(&self, event_id: &EventId) -> Result<PduCount> {
|
|
|
|
|
self.db.get_pdu_count(event_id).await
|
|
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2022-06-19 22:56:14 +02:00
|
|
|
/// Returns the json of a pdu.
|
2024-08-08 17:18:30 +00:00
|
|
|
pub async fn get_pdu_json(&self, event_id: &EventId) -> Result<CanonicalJsonObject> {
|
|
|
|
|
self.db.get_pdu_json(event_id).await
|
2021-08-12 23:04:00 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2022-06-19 22:56:14 +02:00
|
|
|
/// Returns the json of a pdu.
|
2024-07-03 20:06:43 +00:00
|
|
|
#[inline]
|
2024-12-15 00:05:47 -05:00
|
|
|
pub async fn get_non_outlier_pdu_json(
|
|
|
|
|
&self,
|
|
|
|
|
event_id: &EventId,
|
|
|
|
|
) -> Result<CanonicalJsonObject> {
|
2024-08-08 17:18:30 +00:00
|
|
|
self.db.get_non_outlier_pdu_json(event_id).await
|
2021-07-15 19:54:04 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2020-05-26 10:27:51 +02:00
|
|
|
/// Returns the pdu's id.
|
2024-07-03 20:06:43 +00:00
|
|
|
#[inline]
|
2024-12-15 00:05:47 -05:00
|
|
|
pub async fn get_pdu_id(&self, event_id: &EventId) -> Result<RawPduId> {
|
|
|
|
|
self.db.get_pdu_id(event_id).await
|
|
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2021-03-26 11:10:45 +01:00
|
|
|
/// Returns the pdu.
|
2024-07-03 20:06:43 +00:00
|
|
|
#[inline]
|
2025-10-24 14:57:31 -04:00
|
|
|
pub async fn get_non_outlier_pdu(&self, event_id: &EventId) -> Result<PduEvent> {
|
2024-08-08 17:18:30 +00:00
|
|
|
self.db.get_non_outlier_pdu(event_id).await
|
2021-03-26 11:10:45 +01:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2020-05-24 18:25:52 +02:00
|
|
|
/// Returns the pdu.
|
2021-02-01 12:44:30 -05:00
|
|
|
///
|
|
|
|
|
/// Checks the `eventid_outlierpdu` Tree if not found in the timeline.
|
2025-04-27 02:39:28 +00:00
|
|
|
#[inline]
|
2024-12-15 00:05:47 -05:00
|
|
|
pub async fn get_pdu(&self, event_id: &EventId) -> Result<PduEvent> {
|
|
|
|
|
self.db.get_pdu(event_id).await
|
|
|
|
|
}
|
2024-11-06 06:20:39 +00:00
|
|
|
|
2020-05-26 10:27:51 +02:00
|
|
|
/// Returns the pdu.
|
2021-02-03 20:00:01 -05:00
|
|
|
///
|
|
|
|
|
/// This does __NOT__ check the outliers `Tree`.
|
2025-04-27 02:39:28 +00:00
|
|
|
#[inline]
|
2024-12-15 00:05:47 -05:00
|
|
|
pub async fn get_pdu_from_id(&self, pdu_id: &RawPduId) -> Result<PduEvent> {
|
|
|
|
|
self.db.get_pdu_from_id(pdu_id).await
|
|
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2020-11-30 14:46:47 -05:00
|
|
|
/// Returns the pdu as a `BTreeMap<String, CanonicalJsonValue>`.
|
2025-04-27 02:39:28 +00:00
|
|
|
#[inline]
|
2024-11-02 06:12:54 +00:00
|
|
|
pub async fn get_pdu_json_from_id(&self, pdu_id: &RawPduId) -> Result<CanonicalJsonObject> {
|
2024-08-08 17:18:30 +00:00
|
|
|
self.db.get_pdu_json_from_id(pdu_id).await
|
2020-09-15 16:13:54 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2025-01-04 04:12:50 +00:00
|
|
|
/// Checks if pdu exists
|
|
|
|
|
///
|
|
|
|
|
/// Checks the `eventid_outlierpdu` Tree if not found in the timeline.
|
2025-04-27 02:39:28 +00:00
|
|
|
#[inline]
|
2025-01-04 04:12:50 +00:00
|
|
|
pub fn pdu_exists<'a>(
|
|
|
|
|
&'a self,
|
|
|
|
|
event_id: &'a EventId,
|
|
|
|
|
) -> impl Future<Output = bool> + Send + 'a {
|
|
|
|
|
self.db.pdu_exists(event_id).is_ok()
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-09 15:13:17 +02:00
|
|
|
/// Removes a pdu and creates a new one with the same id.
|
2024-07-07 19:03:15 +00:00
|
|
|
#[tracing::instrument(skip(self), level = "debug")]
|
2025-04-27 02:39:28 +00:00
|
|
|
pub async fn replace_pdu(&self, pdu_id: &RawPduId, pdu_json: &CanonicalJsonObject) -> Result {
|
|
|
|
|
self.db.replace_pdu(pdu_id, pdu_json).await
|
2020-05-26 10:27:51 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2024-12-06 03:09:08 +00:00
|
|
|
/// Returns an iterator over all PDUs in a room. Unknown rooms produce no
|
|
|
|
|
/// items.
|
2024-07-03 20:06:43 +00:00
|
|
|
#[inline]
|
2024-12-06 03:09:08 +00:00
|
|
|
pub fn all_pdus<'a>(
|
2024-12-15 00:05:47 -05:00
|
|
|
&'a self,
|
|
|
|
|
room_id: &'a RoomId,
|
2025-01-04 04:12:50 +00:00
|
|
|
) -> impl Stream<Item = PdusIterItem> + Send + 'a {
|
2025-06-03 21:31:02 +01:00
|
|
|
self.pdus(room_id, None).ignore_err()
|
2020-05-03 17:25:31 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2025-10-22 13:06:33 -04:00
|
|
|
/// Reverse iteration starting after `until`.
|
2024-07-07 19:03:15 +00:00
|
|
|
#[tracing::instrument(skip(self), level = "debug")]
|
2025-01-04 04:12:50 +00:00
|
|
|
pub fn pdus_rev<'a>(
|
2024-12-15 00:05:47 -05:00
|
|
|
&'a self,
|
|
|
|
|
room_id: &'a RoomId,
|
|
|
|
|
until: Option<PduCount>,
|
2025-01-04 04:12:50 +00:00
|
|
|
) -> impl Stream<Item = Result<PdusIterItem>> + Send + 'a {
|
2024-11-07 04:49:01 +00:00
|
|
|
self.db
|
2025-06-03 21:31:02 +01:00
|
|
|
.pdus_rev(room_id, until.unwrap_or_else(PduCount::max))
|
2020-05-03 17:25:31 +02:00
|
|
|
}
|
2024-03-05 19:48:54 -05:00
|
|
|
|
2025-10-22 13:06:33 -04:00
|
|
|
/// Forward iteration starting after `from`.
|
2024-07-07 19:03:15 +00:00
|
|
|
#[tracing::instrument(skip(self), level = "debug")]
|
2025-01-04 04:12:50 +00:00
|
|
|
pub fn pdus<'a>(
|
2024-12-15 00:05:47 -05:00
|
|
|
&'a self,
|
|
|
|
|
room_id: &'a RoomId,
|
|
|
|
|
from: Option<PduCount>,
|
2025-01-04 04:12:50 +00:00
|
|
|
) -> impl Stream<Item = Result<PdusIterItem>> + Send + 'a {
|
2025-06-03 21:31:02 +01:00
|
|
|
self.db.pdus(room_id, from.unwrap_or_else(PduCount::min))
|
2020-06-04 13:58:55 +02:00
|
|
|
}
|
2024-10-02 21:18:32 +00:00
|
|
|
}
|