Files
CODE_ASSISTANT/docs/troubleshootings/2026-07-26-snap-reentry-blank-chat.md
T
2026-09-16 17:22:14 +09:00

3.4 KiB

snap 채팅 재진입 시 대화 안 보임 (됐다 안 됐다)

증상

  • 답변 스트리밍 중 목록 갔다 오면 대화가 비어 보이고, 새로고침해야 나타남
  • 재진입 시 답변을 처음부터 타자기로 다시 뿌림
  • "되묻기(의도 애매)" 답변에서 유독 자주 아무것도 안 보임
  • 재현이 타이밍 따라 들쭉날쭉 (됐다 안 됐다)

원인 (겹친 층 4개)

  1. 전역 staleTime: 30_000 (진짜 뿌리) — 세션 detail 캐시가 30초간 refetch 안 됨. 빈/부분 스냅샷이 캐시에 박히면 재진입해도 그대로 나옴. 테스트 들락날락이 다 30초 창 안이라 "새로고침해야 나타남"으로 체감. 아래 3개 수정이 다 "새 데이터 오면" 작동하는 구조였는데 새 데이터 자체가 안 오고 있었음.
  2. remount 시 무조건 재seed — per-instance initedRef 가드는 remount 마다 리셋 → stale DB 스냅샷이 라이브 store 를 덮고 스트림도 abort(seed 가 abort 함).
  3. 타자기 진행도가 컴포넌트 로컬useSmoothedText 의 displayed 가 "" 시작이라 remount 마다 처음부터 재생.
  4. 재진입 시 "생성 중" 표시 없음 — 생성 중 재진입하면 DB 엔 user 만 있어서 시머 없이 백지. 되묻기 경로는 응답이 느려서(관측치 43초) 이 백지 창이 유독 길었음 → "되묻는 부분에서 안 보임"으로 체감.

확정 근거

  • dev DB 직접 조회(asyncpg): 되묻기 포함 모든 메시지 정상 저장돼 있었음 → 백엔드 무죄. 세션 34b5b639: user 06:59:57 → 되묻기 assistant 07:00:40 (len=302, 43초) → 후속 user 07:00:49 → 본답변 07:01:00 (len=1347).
  • 백엔드 streaming.py: persist → usage → done 순서. 클라 끊겨도 producer 가 끝까지 저장 → DB 가 신뢰 가능한 복구원.

수정 (전부 2_frontend/src/features/snap + lib/streaming)

파일 내용
api/snap.api.ts detail 쿼리 staleTime: 0 (재진입마다 refetch) + isGenerating 이면 1.5s 폴링
pages/SessionChatPage.tsx seed 가드: 라이브면 보존, 아니면 "내용량 많은 쪽으로 단조 수렴"(DB > store 일 때만 seed). 재진입+백엔드 생성 중이면 시머 표시 + Composer 잠금(409 방지)
lib/streaming/useSmoothedText.ts displayed 초기값 ""full (remount 시 기존 내용 즉시, 새 토큰만 타자기)
hooks/useSnapChat.ts onDone 에서 detail 캐시 invalidate

교훈

  • "됐다 안 됐다" = 레이스. 코드 추리로 5번 고치다 실패 → DB 직접 조회 한 방에 백엔드 무죄 확정 + 프론트로 범위 좁힘. 증거 수집을 먼저 했어야 함.
  • 전역 캐시 정책(staleTime)은 실시간성 데이터(스트리밍 대화)에 그대로 두면 안 됨 — 쿼리별 override 필수.
  • 하위 층을 아무리 고쳐도 최상층(캐시)이 데이터를 안 내려주면 전부 무력화됨. 층이 겹친 버그는 층별로 분리해서 검증할 것.

남은 한계 (알고 수용)

  • STOP 으로 얼린 부분 답변은 재진입 시 DB 완성본으로 교체됨(백엔드 cancel 미구현이라 어차피 끝까지 생성·저장). "정지 자리 유지"가 필요하면 백엔드 cancel 이 선행.
  • 멀티탭 동시 스트림은 백엔드 단일 프로세스 전제(레지스트리)라 이번 범위 밖.