From 06998c1406aab9943b62d6facb36cdee1cf52115 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 19 Nov 2018 09:18:53 +0900 Subject: [PATCH] Room: process new state events after applying redactions This was one more cause of #257 - the case when a redaction on a state event arrives in the same batch as the redacted event. --- lib/room.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/room.cpp b/lib/room.cpp index 4bd96fc3e..5faff2718 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -192,7 +192,7 @@ class Room::Private is(*ti); } - void addNewMessageEvents(RoomEvents&& events); + bool addNewMessageEvents(RoomEvents&& events); void addHistoricalMessageEvents(RoomEvents&& events); /** Move events into the timeline @@ -1135,24 +1135,15 @@ void Room::updateData(SyncRoomData&& data) if (!data.timeline.empty()) { et.restart(); - // State changes can arrive in a timeline event; so check those. - for (const auto& e: data.timeline) - emitNamesChanged |= processStateEvent(*e); + emitNamesChanged |= d->addNewMessageEvents(move(data.timeline)); if (data.timeline.size() > 9 || et.nsecsElapsed() >= profilerMinNsecs()) - qCDebug(PROFILER) << "*** Room::processStateEvents(timeline):" + qCDebug(PROFILER) << "*** Room::addNewMessageEvents():" << data.timeline.size() << "event(s)," << et; } if (emitNamesChanged) emit namesChanged(this); d->updateDisplayname(); - if (!data.timeline.empty()) - { - et.restart(); - d->addNewMessageEvents(move(data.timeline)); - if (data.timeline.size() > 9 || et.nsecsElapsed() >= profilerMinNsecs()) - qCDebug(PROFILER) << "*** Room::addNewMessageEvents():" << et; - } for( auto&& ephemeralEvent: data.ephemeral ) processEphemeralEvent(move(ephemeralEvent)); @@ -1679,11 +1670,11 @@ inline bool isRedaction(const RoomEventPtr& ep) return is(*ep); } -void Room::Private::addNewMessageEvents(RoomEvents&& events) +bool Room::Private::addNewMessageEvents(RoomEvents&& events) { dropDuplicateEvents(events); if (events.empty()) - return; + return false; // Pre-process redactions so that events that get redacted in the same // batch landed in the timeline already redacted. @@ -1708,6 +1699,15 @@ void Room::Private::addNewMessageEvents(RoomEvents&& events) // If the target event comes later, it comes already redacted. } + // State changes arrive as a part of timeline; the current room state gets + // updated before merging events to the timeline because that's what + // clients historically expect. This may eventually change though if we + // postulate that the current state is only current between syncs but not + // within a sync. + bool emitNamesChanged = false; + for (const auto& eptr: events) + emitNamesChanged |= q->processStateEvent(*eptr); + auto timelineSize = timeline.size(); auto totalInserted = 0; for (auto it = events.begin(); it != events.end();) @@ -1775,6 +1775,7 @@ void Room::Private::addNewMessageEvents(RoomEvents&& events) } Q_ASSERT(timeline.size() == timelineSize + totalInserted); + return emitNamesChanged; } void Room::Private::addHistoricalMessageEvents(RoomEvents&& events)