Skip to content

꼬리질문 스트리밍: seq 재조립 + 타자기 이중 버퍼 제거 - #201

Merged
Jaeho-Site merged 2 commits into
devfrom
fix/streaming-delta-seq
Aug 22, 2026
Merged

꼬리질문 스트리밍: seq 재조립 + 타자기 이중 버퍼 제거#201
Jaeho-Site merged 2 commits into
devfrom
fix/streaming-delta-seq

Conversation

@Jaeho-Site

Copy link
Copy Markdown
Contributor

SESSION_MESSAGE_DELTA{ messageId, seq, text } 로 오는데 프론트 applyDeltaseq 를 버리고 도착 순서대로 append 했다. 발행은 순서대로지만 브로커→WS fan-out 경로가 프레임 순서·전달을 보장하지 않으므로, 순서가 뒤바뀐 프레임은 질문 텍스트를 종료 reconcile 까지 오염시키고("동시성 어떻게 해결했나요?문제를 "), 재전달 프레임은 같은 조각을 두 번 붙였다.

그 위에 useTypewriter(35ms interval)가 이미 토큰 단위로 오는 실스트림을 다시 애니메이션 — 표시가 실스트림보다 뒤처지는 이중 버퍼였다.

무엇

seq 기반 재조립 (streamingBuffer.ts)

  • 버퍼를 messageId→(seq→조각) 맵으로 교체. 표시 텍스트는 seq 0부터 연속된 구간만 join (bufferedText).
  • 순서 역전은 정렬로 흡수, 중복 seq 는 멱등(첫 값 유지), 갭은 채워질 때까지 hold — 정말 유실되면 기존 종료 reconcile(콜백 후 GET messages 정본)이 덮는다. 잘못된 문장을 보여주느니 잠시 멈추는 쪽을 택했다.
  • seq 0 도착 전엔 undefined 를 돌려 placeholder("생성 중") 표시를 유지한다.
  • 핸들러는 payload.seq 타입까지 방어 검증 — 새 알고리즘에선 비정상 seq 가 조용히 영구 드롭되는 실패 모드라서다.
  • docs/event-stream.md §3.3-1 에 이 소비 규칙을 명시했다.

타자기 제거 (QuestionBubble·StageQuestion)

델타 실스트림이 곧 애니메이션이다 — 재애니메이션 없이 content 를 직접 표시하고 훅·테스트를 삭제했다. 첫 델타부터 화면 표시까지의 인위적 지연(TTFT 왜곡)과 35ms 상태 갱신 루프가 사라진다. 타자기 게이트 용도뿐이던 QuestionBubblestreaming prop 도 함께 제거.

검증

  • streamingBuffer 단위 테스트 8케이스: 정상 순서 / 역전 재조립 / 중복 멱등 / 갭 hold / 갭 채움 재개 / seq 0 미도착 placeholder / 메시지 격리 / sentinel 판별.
  • 전체 npm run test 138 통과 / 0 실패, npm run build·npm run lint 클린.
  • deltaBuffer 는 서버 content 확정 시 messageId 별로 삭제되는 기존 cleanup 그대로 — 누수 없음. placeholder·턴 게이팅 로직 불변.

트레이드오프

seq 0 프레임이 유실되는 드문 경우 해당 꼬리질문은 스트리밍 표시 없이 placeholder 로 있다가 종료 시 한 번에 나타난다 — 오염 표시보다 안전한 쪽.

- applyDelta 가 seq 를 무시하고 단순 append — 순서 뒤바뀐 WS 프레임이
  질문 텍스트를 종료 reconcile 까지 오염시키고, 재전달 프레임은 중복 표시됐다
- messageId→(seq→조각) 버퍼로 교체, 표시는 seq 0부터 연속 prefix 만 join
  (bufferedText 선택자) — 역전은 정렬로 흡수, 중복은 멱등, 갭은 채워질 때까지
  hold 하고 유실 시 기존 종료 reconcile 이 정본으로 덮는다
- 핸들러에 seq 타입 방어 검증 추가, 단위 테스트 8케이스
- event-stream.md §3.3-1 에 소비 규칙 명시
- 델타가 이미 토큰 단위로 도착하는데 useTypewriter(35ms interval)가 그 위에
  재애니메이션 — 이중 버퍼로 표시가 실스트림보다 뒤처지고 타이머 루프가 돌았다
- 사용처 2곳(QuestionBubble·StageQuestion)에서 content 직접 표시로 전환,
  훅·테스트 삭제. 타자기 게이트 용도뿐이던 QuestionBubble 의 streaming prop 제거
@Jaeho-Site
Jaeho-Site merged commit 08b016f into dev Aug 22, 2026
5 checks passed
@Jaeho-Site
Jaeho-Site deleted the fix/streaming-delta-seq branch August 22, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant