읽지 않은 히스토리를 따라잡는 중에 누군가 게시하면 채팅에서 메시지 블록이 건너뛰기됨

채널이나 DM에 첫 페이지에 로드되는 양보다 많은 읽지 않은 메시지가 있을 때, 사용자가 해당 기록을 스크롤하는 도중에 누군가가 글을 게시하면, 로드된 페이지의 끝에서 새로 들어온 실시간 메시지까지의 모든 메시지가 건너뛰어집니다. 목록이 이전 메시지들에서 바로 실시간 메시지(종종 몇 시간 이후)로 점프하며, 아무것도 누락되었다는 표시가 나타나지 않습니다. 채널을 새로고침하면 간격을 한 페이지씩 채우므로, 큰 간격은 여러 번의 새로고침을 필요로 합니다.

이 현상은 브라우저나 기기 유형과 무관하게 발생합니다(Firefox 데스크톱 및 Android, Chrome Android PWA에서 테스트함).

재현 단계:

  1. 사용자 A와 사용자 B가 DM이나 채널을 공유합니다. 사용자 A는 최신 메시지까지 읽고 떠납니다.
  2. 사용자 B가 60개 이상의 메시지를 게시합니다.
  3. 사용자 A가 DM을 엽니다. 마지막으로 읽은 메시지 주변이 로드됩니다(그 아래에 더 최신인 메시지 25개 있음).
  4. 로드된 페이지의 맨 아래까지 스크롤하기 전에, 사용자 B가 메시지를 하나 더 게시합니다.
  5. 사용자 A가 아래로 스크롤합니다.

기대 동작: 그 아래에 다음 25개 메시지 페이지가 로드되고, 실시간 메시지에 도달할 때까지 반복됩니다.

실제 동작: 로드된 페이지 바로 뒤에 실시간 메시지가 나타납니다. 맨 아래에 도달하면 실시간 메시지 이후의 메시지를 요청하는데, 응답은 비어 있으며, can_load_more_future는 false가 되고, 그 사이의 35개 이상의 메시지는 절대 표시되지 않습니다. 실시간 메시지가 이제 보이게 되었으므로 last_read_message_id가 간격을 넘어 진행되어, 읽지 않음 표시도 사라집니다.

여기에는 이 현상이 발생하는 이유에 대한 저의 최선의 추측이 있습니다:

2025년 12월경의 커밋(“FEATURE: respect user presence when chat is on screen”, #36652) 이후, ChatChannel#onNewMessage는 항상 메시지를 ChatPaneState#handleIncomingMessage를 통해 라우팅합니다. 이 함수는 자동 스크롤 시 addMessage를 호출하고, 그렇지 않을 경우 maintainScrollPosition을 통해 호출합니다.

ChatMessagesLoader#computeNextTargetMessage는 FUTURE 페이지의 커서로 목록에 있는 마지막 비스테이지(non-staged) 메시지를 사용합니다. partially loaded(부분적으로 로드된) 목록의 끝에 실시간 메시지가 놓이게 되면, 해당 커서는 로드되지 않은 모든 기록을 뛰어넘어 점프합니다.

그리고 Chat::MessagesQuery.query_paginated_messages는 FUTURE 페이지에 대해서만 can_load_more_future를, PAST 페이지에 대해서만 can_load_more_past를 설정합니다. 다른 하나는 nil입니다. ChatMessagesLoader#loadMore는 result.meta로부터 두 값을 조건 없이 할당하므로, 마지막으로 읽은 상태에서 열었을 때 조금 위로 스크롤하는 PAST 페이지 하나만으로도 canLoadMoreFuture가 null로 설정되어 그 아래에 기록이 아직 로드되지 않았음에도 불구하고 계속됩니다. 추가 페이징은 loadMore가 === false을 확인하기 때문에 여전히 작동합니다.

또한, #sendNewMessage는 canLoadMoreFuture가 true일 때 최신 페이지를 로드하지 않고 목록 끝에 메시지를 스테이지하는 별개의 오래된 버그가 존재합니다. 이 메시지가 확인되면 FUTURE 커서가 되므로, 읽던 기록에서 이전 메시지에 답장을 할 경우 동일한 건너뛰기가 발생합니다.

저희 커뮤니티는 주로 채팅에 초점을 맞추고 있지 않지만, 사용자들은 과거 메시지를 자주 다시 읽습니다. 따라서 자신이 참여하지 않았던 진행 중인 대화에서 메시지가 누락되는 것은 문제가 됩니다. 특히 홈 페이지로 채팅을 설정할 수 있는 새로운 기능이 추가된 점을 고려하면, 주요 목적이 채팅인 커뮤니티에서는 더 큰 문제가 될 것으로 생각됩니다.