mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-14 04:37:00 +00:00
fix: Ask more servers for state_ids when origin fails to provide
Some servers reference events in prev_events that they might not yet have finished processing, so this allows us to at least attempt to get the state from another trustworthy server in the room that might be faster. I don't think this is too effective, however it's more effective than giving up immediately.
This commit is contained in:
1 file changed
+44
-4
@@ -6,9 +6,9 @@ use std::{
|
||||
use conduwuit::{
|
||||
Err, Event, PduEvent, Result, debug, debug_warn, err, error, trace, utils::IterStream, warn,
|
||||
};
|
||||
use futures::StreamExt;
|
||||
use futures::{StreamExt, TryFutureExt, future::select_ok};
|
||||
use ruma::{
|
||||
EventId, OwnedEventId, RoomId, ServerName,
|
||||
EventId, OwnedEventId, OwnedRoomId, RoomId, ServerName,
|
||||
api::federation::event::{get_room_state, get_room_state_ids},
|
||||
};
|
||||
|
||||
@@ -35,7 +35,7 @@ impl super::Service {
|
||||
event_id: &EventId,
|
||||
) -> Result<Option<HashMap<u64, OwnedEventId>>> {
|
||||
trace!(%origin, "Asking remote for state_ids");
|
||||
let res: get_room_state_ids::v1::Response = self
|
||||
let res: get_room_state_ids::v1::Response = match self
|
||||
.services
|
||||
.sending
|
||||
.send_federation_request(
|
||||
@@ -43,7 +43,20 @@ impl super::Service {
|
||||
get_room_state_ids::v1::Request::new(event_id.to_owned(), room_id.to_owned()),
|
||||
)
|
||||
.await
|
||||
.inspect_err(|e| debug_warn!("Fetching state for event failed: {e}"))?;
|
||||
.inspect_err(|e| debug_warn!("Fetching state for event failed: {e}"))
|
||||
{
|
||||
| Ok(resp) => Ok(resp),
|
||||
| Err(e) =>
|
||||
if e.is_not_found() {
|
||||
self.fetch_state_ids_from_backfill_servers(
|
||||
event_id.to_owned(),
|
||||
room_id.to_owned(),
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
Err(e)
|
||||
},
|
||||
}?;
|
||||
|
||||
debug!(events = res.pdu_ids.len(), "Fetching state events");
|
||||
let mut state_events: HashMap<OwnedEventId, PduEvent> =
|
||||
@@ -160,6 +173,33 @@ impl super::Service {
|
||||
Ok(Some(state))
|
||||
}
|
||||
|
||||
async fn fetch_state_ids_from_backfill_servers(
|
||||
&self,
|
||||
event_id: OwnedEventId,
|
||||
room_id: OwnedRoomId,
|
||||
) -> Result<get_room_state_ids::v1::Response> {
|
||||
let candidates = self
|
||||
.services
|
||||
.timeline
|
||||
.candidate_backfill_servers(&room_id)
|
||||
.await;
|
||||
debug!(%room_id, ?candidates, "Asking backfill servers for state_ids");
|
||||
let futures = candidates.iter().map(|server_name| {
|
||||
Box::pin(
|
||||
self.services
|
||||
.sending
|
||||
.send_federation_request(
|
||||
server_name,
|
||||
get_room_state_ids::v1::Request::new(event_id.clone(), room_id.clone()),
|
||||
)
|
||||
.inspect_err(|e| {
|
||||
debug_warn!("Fallback fetching state for event failed: {e}");
|
||||
}),
|
||||
)
|
||||
});
|
||||
Ok(select_ok(futures).await?.0)
|
||||
}
|
||||
|
||||
/// Fetches the full state via `GET /_matrix/federation/v1/state` from a
|
||||
/// remote server, and persists all the incoming auth chain events and
|
||||
/// state events as outliers, for use later.
|
||||
|
||||
Reference in new issue
Block a user