mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
fix(sync/v3): Cleanup part 1: mostly fix redundant data in state
This commit is contained in:
+58
-25
@@ -3,12 +3,13 @@ mod v4;
|
||||
mod v5;
|
||||
|
||||
use conduwuit::{
|
||||
Error, PduCount, Result,
|
||||
PduCount, Result,
|
||||
matrix::pdu::PduEvent,
|
||||
trace,
|
||||
utils::stream::{BroadbandExt, ReadyExt, TryIgnore},
|
||||
};
|
||||
use conduwuit_service::Services;
|
||||
use futures::{StreamExt, pin_mut};
|
||||
use futures::StreamExt;
|
||||
use ruma::{
|
||||
RoomId, UserId,
|
||||
events::TimelineEventType::{
|
||||
@@ -23,43 +24,75 @@ pub(crate) use self::{
|
||||
pub(crate) const DEFAULT_BUMP_TYPES: &[TimelineEventType; 6] =
|
||||
&[CallInvite, PollStart, Beacon, RoomEncrypted, RoomMessage, Sticker];
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct TimelinePdus {
|
||||
pub pdus: Vec<(PduCount, PduEvent)>,
|
||||
pub limited: bool,
|
||||
}
|
||||
|
||||
async fn load_timeline(
|
||||
services: &Services,
|
||||
sender_user: &UserId,
|
||||
room_id: &RoomId,
|
||||
roomsincecount: PduCount,
|
||||
next_batch: Option<PduCount>,
|
||||
starting_count: Option<PduCount>,
|
||||
ending_count: Option<PduCount>,
|
||||
limit: usize,
|
||||
) -> Result<(Vec<(PduCount, PduEvent)>, bool), Error> {
|
||||
) -> Result<TimelinePdus> {
|
||||
let last_timeline_count = services
|
||||
.rooms
|
||||
.timeline
|
||||
.last_timeline_count(Some(sender_user), room_id)
|
||||
.await?;
|
||||
|
||||
if last_timeline_count <= roomsincecount {
|
||||
return Ok((Vec::new(), false));
|
||||
let mut pdus_between_counts = match starting_count {
|
||||
| Some(starting_count) => {
|
||||
if last_timeline_count <= starting_count {
|
||||
return Ok(TimelinePdus::default());
|
||||
}
|
||||
|
||||
// Stream from the DB all PDUs which were sent after `starting_count` but before
|
||||
// `ending_count`, including both endpoints
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.pdus(Some(sender_user), room_id, Some(starting_count))
|
||||
.ignore_err()
|
||||
.ready_take_while(|&(pducount, _)| {
|
||||
pducount <= ending_count.unwrap_or_else(PduCount::max)
|
||||
})
|
||||
.boxed()
|
||||
},
|
||||
| None => {
|
||||
// For initial sync, stream from the DB all PDUs before and including
|
||||
// `ending_count` in reverse order
|
||||
services
|
||||
.rooms
|
||||
.timeline
|
||||
.pdus_rev(Some(sender_user), room_id, ending_count)
|
||||
.ignore_err()
|
||||
.boxed()
|
||||
},
|
||||
};
|
||||
|
||||
// Return at most `limit` PDUs from the stream
|
||||
let mut pdus: Vec<_> = pdus_between_counts.by_ref().take(limit).collect().await;
|
||||
if starting_count.is_none() {
|
||||
// `pdus_rev` returns PDUs in reverse order. fix that here
|
||||
pdus.reverse();
|
||||
}
|
||||
// The timeline is limited if more than `limit` PDUs exist in the DB after
|
||||
// `starting_count`
|
||||
let limited = pdus_between_counts.next().await.is_some();
|
||||
|
||||
let non_timeline_pdus = services
|
||||
.rooms
|
||||
.timeline
|
||||
.pdus_rev(Some(sender_user), room_id, None)
|
||||
.ignore_err()
|
||||
.ready_skip_while(|&(pducount, _)| pducount > next_batch.unwrap_or_else(PduCount::max))
|
||||
.ready_take_while(|&(pducount, _)| pducount > roomsincecount);
|
||||
trace!(
|
||||
"syncing {:?} timeline pdus from {:?} to {:?} (limited = {:?})",
|
||||
pdus.len(),
|
||||
starting_count,
|
||||
ending_count,
|
||||
limited,
|
||||
);
|
||||
|
||||
// Take the last events for the timeline
|
||||
pin_mut!(non_timeline_pdus);
|
||||
let timeline_pdus: Vec<_> = non_timeline_pdus.by_ref().take(limit).collect().await;
|
||||
|
||||
let timeline_pdus: Vec<_> = timeline_pdus.into_iter().rev().collect();
|
||||
|
||||
// They /sync response doesn't always return all messages, so we say the output
|
||||
// is limited unless there are events in non_timeline_pdus
|
||||
let limited = non_timeline_pdus.next().await.is_some();
|
||||
|
||||
Ok((timeline_pdus, limited))
|
||||
Ok(TimelinePdus { pdus, limited })
|
||||
}
|
||||
|
||||
async fn share_encrypted_room(
|
||||
|
||||
Reference in New Issue
Block a user