Skip to content

Commit 6116c64

Browse files
committed
fix sliding sync recursion by avoiding notif fixup reentry
1 parent 02573cd commit 6116c64

4 files changed

Lines changed: 38 additions & 15 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
default: patch
3+
---
4+
5+
Fix the call stack size crash on load when sliding sync is enabled.

src/app/state/room/roomToUnread.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,8 @@ export const useBindRoomToUnreadAtom = (mx: MatrixClient, unreadAtom: typeof roo
312312
if (room.getMyMembership() !== (KnownMembership.Join as string)) return;
313313

314314
const unreadInfo = getUnreadInfo(room, {
315-
applyFixup: shouldApplyUnreadFixup(),
315+
// Counts are already updated before this event would recurse if true
316+
applyFixup: false,
316317
mDirects,
317318
});
318319
if (unreadInfo.total === 0 && unreadInfo.highlight === 0) {

src/app/utils/room.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,17 @@ type UnreadInfoOptions = {
287287
mDirects?: Set<string>;
288288
};
289289

290+
const unreadInfoFixupInProgress = new WeakSet<Room>();
291+
290292
export const getUnreadInfo = (room: Room, options?: UnreadInfoOptions): UnreadInfo => {
291293
const userId = room.client.getUserId();
292-
if (userId && options?.applyFixup) {
293-
// Reconcile known notification-count drift (notably with Sliding Sync / mixed receipts).
294-
room.fixupNotifications(userId);
294+
if (userId && options?.applyFixup && !unreadInfoFixupInProgress.has(room)) {
295+
unreadInfoFixupInProgress.add(room);
296+
try {
297+
room.fixupNotifications(userId);
298+
} finally {
299+
unreadInfoFixupInProgress.delete(room);
300+
}
295301
}
296302

297303
let total = room.getUnreadNotificationCount(NotificationCountType.Total);

src/client/initMatrix.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,17 @@ type MatrixClientWithWritableFetchRoomEvent = MatrixClient & {
5656
fetchRoomEvent: (roomId: string, eventId: string) => Promise<FetchRoomEventResult>;
5757
};
5858

59-
// Replace fetchRoomEvent for first sync so thread roots don't each trigger GET /event
60-
// Uses cached timeline events when present otherwise a stub that fetches when user opens thread
61-
function installStartupFetchRoomEventPatch(mx: MatrixClient): void {
59+
type StartupFetchRoomEventPatchOptions = {
60+
stubOnCacheMiss: boolean;
61+
};
62+
63+
function installStartupFetchRoomEventPatch(
64+
mx: MatrixClient,
65+
options: StartupFetchRoomEventPatchOptions
66+
): void {
6267
fetchRoomEventStartupCleanupByClient.get(mx)?.();
6368

69+
const { stubOnCacheMiss } = options;
6470
const mxWritable = mx as MatrixClientWithWritableFetchRoomEvent;
6571
const origFetchRoomEvent = mx.fetchRoomEvent.bind(mx);
6672
let restored = false;
@@ -84,12 +90,17 @@ function installStartupFetchRoomEventPatch(mx: MatrixClient): void {
8490
mxWritable.fetchRoomEvent = (roomId: string, eventId: string) => {
8591
if (restored) return origFetchRoomEvent(roomId, eventId);
8692
const cachedEvent = mx.getRoom(roomId)?.findEventById(eventId);
87-
// Reuse sync payload instead of another GET when we already have the root.
88-
const payload: FetchRoomEventResult = cachedEvent?.event ?? {
89-
event_id: eventId,
90-
room_id: roomId,
91-
};
92-
return Promise.resolve(payload);
93+
if (cachedEvent) {
94+
return Promise.resolve(cachedEvent.event);
95+
}
96+
if (stubOnCacheMiss) {
97+
const payload: FetchRoomEventResult = {
98+
event_id: eventId,
99+
room_id: roomId,
100+
};
101+
return Promise.resolve(payload);
102+
}
103+
return origFetchRoomEvent(roomId, eventId);
93104
};
94105

95106
mx.on(ClientEvent.Sync, onSync);
@@ -518,7 +529,7 @@ export const startClient = async (mx: MatrixClient, config?: StartClientConfig):
518529
(filterDefinition.room.timeline as { lazy_load_members?: boolean }).lazy_load_members = true;
519530
}
520531

521-
installStartupFetchRoomEventPatch(mx);
532+
installStartupFetchRoomEventPatch(mx, { stubOnCacheMiss: true });
522533

523534
let syncStarted: Promise<void>;
524535
try {
@@ -693,7 +704,7 @@ export const startClient = async (mx: MatrixClient, config?: StartClientConfig):
693704
});
694705

695706
try {
696-
installStartupFetchRoomEventPatch(mx);
707+
installStartupFetchRoomEventPatch(mx, { stubOnCacheMiss: false });
697708
await mx.startClient({
698709
lazyLoadMembers: true,
699710
slidingSync: manager.slidingSync,

0 commit comments

Comments
 (0)