Repository navigation
fix(chat): settle the chats list in one update after launch - #1665
Merged
Merged
Conversation
Share the in-flight feed sync with onStart and push refreshes, write DM and group feeds (rows, members, previews) in one transaction, make catch-up a single forward-only metadata write, rebuild the list when a chat's newest message changes, and stage read stamps into the reconcile with bounded concurrency. Catch-up now runs the open chat first.
A feed response in flight while a stream event advanced a row overwrote last_activity and last_message_id with older server values, rolling the row back. The feed upsert now takes MAX on last_activity and replaces last_message_id only when strictly newer. Other feed-owned fields are unchanged.
A push refresh that lands mid-sync joined that sync, which may have fetched before the change. It now also queues a single trailing run, coalesced across pushes. onStart, reconnect and heartbeat still only share the in-flight sync.
The first-frame draw passed no sender profiles, so a cold launch drew group previews without the sender prefix until the user_profiles read landed. Names are already persisted there; expose the last read synchronously and use it for that draw. Adds tests that a stored name is in the next session's first emission and that re-storing an unchanged name does not re-emit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On cold launch the chats list painted from Room and then kept changing: rows reordered, previews lagged, and unread dots turned into counts a moment later. The list should be current the first time it settles, with only new events changing it after that, and launch must not get slower.
Why it churned
onStartcalledsyncFeeds()while the login sync was still running, which cancelled it (syncJob?.cancel()) and started over.chat_metadataandchat_members, so each of those transactions rebuilt the list.loadMessages,performDeltaSync) made three separate metadata writes and setlast_activityfrom the newest message even when nothing was new, so rows moved one at a time afterSynced.chat_messages, so a reorder could land before its preview, and the preview stayed stale until an unrelated write.What changes
onStart, reconnect and the heartbeat join the in-flight sync instead of restarting it. A push-triggeredrefreshFeedjoins it and queues one trailing re-run, coalesced across pushes, so a message that landed mid-sync isn't missed.reconcileFeedsfetches the DM and group feeds together, thenChatFeedWriterwrites metadata, members and previews for both in one Room transaction. The wait for both is capped at 2s; a slower feed is written when it arrives.ChatMetadataDao.applyCatchUpis one forward-only update shared by catch-up, stream events and pushed messages.last_message_idandlast_activitymove only for a strictly newer message, so a catch-up with nothing new changes no rows.MAXonlast_activity, strictly newerlast_message_id), so an older feed response can't roll back a row a stream event just advanced. iOS found the same race with a test.observeLatestVisibleChanges(), de-duplicated, so the list rebuilds when a chat's newest visible message changes, including edits and deletes.Tests:
FeedReconcileTest(one write for DM and group,onStartshares the sync, one push or five pushes during a sync produce one trailing fetch),ChatMetadataCatchUpTestandChatFeedUpsertClampTest(Robolectric with real Room: equal or older data leaves the row unchanged), plus updated messaging and feed tests.Every
chat_messageswrite now re-runs a newest-per-chat query, and its cost on a large database hasn't been measured.iOS counterpart: code-payments/code-ios-app#947.