Files
continuwuity/src/service/rooms/event_handler/fetch_prev.rs
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

91 lines
2.5 KiB
Rust
Raw Normal View History

2026-05-26 01:00:12 +01:00
use std::collections::{HashMap, HashSet};
2024-11-08 07:30:52 +00:00
2026-05-26 01:00:12 +01:00
use conduwuit::{
Event, PduEvent, debug, debug_info,
result::DebugInspect,
utils::{BoolExt, IterStream, stream::BroadbandExt},
};
use futures::StreamExt;
use ruma::{RoomId, ServerName};
2024-11-08 07:30:52 +00:00
2026-05-10 01:36:15 +01:00
use crate::rooms::event_handler::build_local_dag;
2024-11-08 07:30:52 +00:00
2026-05-10 01:36:15 +01:00
impl super::Service {
2026-05-26 01:00:12 +01:00
/// Fetches any missing prev_events for this event and persists them before
/// returning.
2026-05-10 01:36:15 +01:00
pub(super) async fn fetch_prevs(
&self,
room_id: &RoomId,
create_event: &PduEvent,
incoming_pdu: &PduEvent,
origin: &ServerName,
) -> conduwuit::Result<()> {
2026-05-26 01:00:12 +01:00
let missing = incoming_pdu
.prev_events()
.stream()
.broad_filter_map(|event_id| async move {
self.services
.timeline
.get_non_outlier_pdu_json(event_id)
.await
.inspect(|_| debug!("Found prev_event {event_id} locally."))
.inspect_err(|e| debug!(%e, "Could not find prev_event {event_id} locally."))
.is_ok()
.or(|| event_id.to_owned())
})
.collect::<Vec<_>>()
.await;
if missing.is_empty() {
debug!(event_id=%incoming_pdu.event_id(), "No missing prev events.");
return Ok(());
}
debug!(%room_id, event_id=%incoming_pdu.event_id(), ?missing, "Fetching previous events");
let tail = self
.services
.state
.get_forward_extremities(room_id)
.collect::<Vec<_>>()
.await;
2024-11-08 07:30:52 +00:00
2026-05-26 01:00:12 +01:00
let backfilled = self
.backfill_missing_events(
room_id.to_owned(),
HashSet::from_iter(vec![incoming_pdu.event_id().to_owned()]),
tail,
origin.to_owned(),
)
.await?;
debug_info!("Fetched {} missing events", backfilled.len());
// Persist all fetched events
let mapped = backfilled
.iter()
.map(|(eid, evt)| {
let mut obj = evt.to_canonical_object();
obj.remove("event_id"); // event_id is inserted by backfill_missing_events
(eid.clone(), obj)
})
.collect::<HashMap<_, _>>();
let to_persist = if mapped.len() <= 1 {
mapped.keys().map(ToOwned::to_owned).collect()
} else {
build_local_dag(&mapped).await?
};
for event_id in to_persist {
debug_info!("Persisting fetched prev event {event_id}");
let pdu_event = backfilled.get(&event_id).cloned().unwrap_or_else(|| {
panic!("Event {event_id} was in backfill response but not in map")
});
let obj = pdu_event.to_canonical_object();
self.upgrade_outlier_to_timeline_pdu(pdu_event, obj, create_event, origin, room_id)
.await
.debug_inspect(|_| debug_info!("Persisted fetched prev event {event_id}"))?;
2024-11-08 07:30:52 +00:00
}
2026-05-10 01:36:15 +01:00
2026-05-26 01:00:12 +01:00
// NOTE because i keep forgetting: the caller persists incoming_pdu.
// we only care about its prev events
2026-05-10 01:36:15 +01:00
Ok(())
2024-11-08 07:30:52 +00:00
}
}