Fix partial v3 syncs on post-timeout pass; fix partial state on room join.

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-07-27 05:44:10 +00:00
parent 2e0b156de0
commit 59b62b1453
4 changed files with 103 additions and 53 deletions

View File

@@ -58,6 +58,11 @@ pub async fn update_membership(
match &membership {
| MembershipState::Join => {
// Increment the counter for a unique value and hold the guard even though the
// value is not used. This will allow proper sync to clients similar to the
// other membership state changes.
let _next_count = self.services.globals.next_count();
// Check if the user never joined this room
if !self.once_joined(user_id, room_id).await {
// Add the user ID to the join list then
@@ -236,7 +241,7 @@ pub async fn update_joined_count(&self, room_id: &RoomId) {
/// `update_membership` instead
#[implement(super::Service)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn mark_as_joined(&self, user_id: &UserId, room_id: &RoomId) {
pub(crate) fn mark_as_joined(&self, user_id: &UserId, room_id: &RoomId) {
let userroom_id = (user_id, room_id);
let userroom_id = serialize_key(userroom_id).expect("failed to serialize userroom_id");
@@ -271,7 +276,7 @@ pub fn mark_as_joined(&self, user_id: &UserId, room_id: &RoomId) {
/// `update_membership` instead
#[implement(super::Service)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn mark_as_left(&self, user_id: &UserId, room_id: &RoomId) {
pub(crate) fn mark_as_left(&self, user_id: &UserId, room_id: &RoomId) {
let count = self.services.globals.next_count();
let userroom_id = (user_id, room_id);
@@ -315,7 +320,7 @@ pub fn mark_as_left(&self, user_id: &UserId, room_id: &RoomId) {
/// `update_membership` instead
#[implement(super::Service)]
#[tracing::instrument(skip(self), level = "debug")]
pub fn mark_as_knocked(
pub(crate) fn mark_as_knocked(
&self,
user_id: &UserId,
room_id: &RoomId,
@@ -372,7 +377,7 @@ fn mark_as_once_joined(&self, user_id: &UserId, room_id: &RoomId) {
#[implement(super::Service)]
#[tracing::instrument(level = "debug", skip(self, last_state, invite_via))]
pub async fn mark_as_invited(
pub(crate) async fn mark_as_invited(
&self,
user_id: &UserId,
room_id: &RoomId,

View File

@@ -159,27 +159,29 @@ where
.await;
let insert_lock = self.mutex_insert.lock(pdu.room_id()).await;
let count1 = self.services.globals.next_count();
let count2 = self.services.globals.next_count();
let next_count1 = self.services.globals.next_count();
let next_count2 = self.services.globals.next_count();
// Mark as read first so the sending client doesn't get a notification even if
// appending fails
self.services
.read_receipt
.private_read_set(pdu.room_id(), pdu.sender(), *count1);
.private_read_set(pdu.room_id(), pdu.sender(), *next_count2);
self.services
.user
.reset_notification_counts(pdu.sender(), pdu.room_id());
let count2 = PduCount::Normal(*count2);
let pdu_id: RawPduId = PduId { shortroomid, shorteventid: count2 }.into();
let count = PduCount::Normal(*next_count1);
let pdu_id: RawPduId = PduId { shortroomid, shorteventid: count }.into();
// Insert pdu
self.db
.append_pdu(&pdu_id, pdu, &pdu_json, count2)
.append_pdu(&pdu_id, pdu, &pdu_json, count)
.await;
drop(next_count1);
drop(next_count2);
drop(insert_lock);
// See if the event matches any known pushers via power level
@@ -396,7 +398,7 @@ where
{
self.services
.pdu_metadata
.add_relation(count2, related_pducount);
.add_relation(count, related_pducount);
}
}
@@ -408,7 +410,7 @@ where
if let Ok(related_pducount) = self.get_pdu_count(&in_reply_to.event_id).await {
self.services
.pdu_metadata
.add_relation(count2, related_pducount);
.add_relation(count, related_pducount);
}
},
| Relation::Thread(thread) => {