fix: Additional sync logic fixes

This commit is contained in:
Ginger
2026-05-26 14:28:08 -04:00
parent b6158c73db
commit 7f21f0d6ab
+32 -25
View File
@@ -366,8 +366,7 @@ async fn fetch_shortstatehashes(
.await?; .await?;
// The room state as of the end of the last sync. // The room state as of the end of the last sync.
// This will be None if we are doing an initial sync or if we just joined this // This will be None if we are doing an initial sync.
// room.
let last_sync_end_shortstatehash = let last_sync_end_shortstatehash =
OptionFuture::from(last_sync_end_count.map(async |last_sync_end_count| { OptionFuture::from(last_sync_end_count.map(async |last_sync_end_count| {
pin! { pin! {
@@ -390,7 +389,7 @@ async fn fetch_shortstatehashes(
.map_err(|err| err!("Last sync end PDU has no shortstatehash: {err}")) .map_err(|err| err!("Last sync end PDU has no shortstatehash: {err}"))
}, },
| None => { | None => {
// No events have been sent since the last sync, // No events have been sent since the last sync, or we just joined this room,
// so the state then is the same as the state now // so the state then is the same as the state now
Ok(current_shortstatehash) Ok(current_shortstatehash)
}, },
@@ -465,13 +464,19 @@ async fn build_state_events(
last_sync_end_shortstatehash, last_sync_end_shortstatehash,
} = shortstatehashes; } = shortstatehashes;
let timeline_start_shortstatehash = if let Some((_, pdu)) = timeline.pdus.front() { let timeline_start_shortstatehash = if let Some((count, pdu)) = timeline.pdus.front() {
services if matches!(count, PduCount::Backfilled(_)) {
.rooms // We don't have shortstatehashes for backfilled PDUs, the best we can
.state_accessor // do is to use the current state
.pdu_shortstatehash(&pdu.event_id) current_shortstatehash
.await } else {
.map_err(|err| err!("Timeline start has no shortstatehash: {err}"))? services
.rooms
.state_accessor
.pdu_shortstatehash(&pdu.event_id)
.await
.map_err(|err| err!("Timeline start has no shortstatehash: {err}"))?
}
} else { } else {
// if the timeline is empty there can't possibly be any changes to the state // if the timeline is empty there can't possibly be any changes to the state
return Ok(vec![]); return Ok(vec![]);
@@ -594,23 +599,25 @@ async fn check_joined_since_last_sync(
ShortStateHashes { last_sync_end_shortstatehash, .. }: ShortStateHashes, ShortStateHashes { last_sync_end_shortstatehash, .. }: ShortStateHashes,
SyncContext { syncing_user, .. }: SyncContext<'_>, SyncContext { syncing_user, .. }: SyncContext<'_>,
) -> Result<bool> { ) -> Result<bool> {
// fetch the syncing user's membership event during the last sync. let Some(last_sync_end_shortstatehash) = last_sync_end_shortstatehash else {
// this will be None if `previous_sync_end_shortstatehash` is None. // For initial syncs always return false, since there's no "last sync" for the
let membership_during_previous_sync = match last_sync_end_shortstatehash { // user to have joined since.
| Some(last_sync_end_shortstatehash) => services return Ok(false);
.rooms
.state_accessor
.state_get_content(
last_sync_end_shortstatehash,
&StateEventType::RoomMember,
syncing_user.as_str(),
)
.await
.inspect_err(|_| debug_warn!("User has no previous membership"))
.ok(),
| None => None,
}; };
// Fetch the syncing user's membership event during the last sync.
let membership_during_previous_sync = services
.rooms
.state_accessor
.state_get_content(
last_sync_end_shortstatehash,
&StateEventType::RoomMember,
syncing_user.as_str(),
)
.await
.inspect_err(|_| debug_warn!("User has no previous membership"))
.ok();
// TODO: If the requesting user got state-reset out of the room, this // TODO: If the requesting user got state-reset out of the room, this
// will be `true` when it shouldn't be. this function should never be called // will be `true` when it shouldn't be. this function should never be called
// in that situation, but it may be if the membership cache didn't get updated. // in that situation, but it may be if the membership cache didn't get updated.