728x90

SSE 2

[비동기] 스트리밍 도중 클라이언트 끊김 진행 작업 shield 복구

부제: 사용자가 응답 도중 앱을 닫아도, 생성 중이던 답을 잃지 않게 한 이야기챗봇은 답을 스트리밍(SSE)으로 한 조각씩 흘려보낸다.그런데 사용자가 답이 끝나기 전에 앱을 닫거나 화면을 나가면 연결이 끊긴다.문제는 그 순간 서버가 무엇을 하느냐였다.끊기면 진행 중이던 답이 사라진다연결이 끊기면 서버(uvicorn)는 그 요청에 딸린 작업들을 통째로 취소한다.비동기에서 요청 하나는 여러 작업이 묶인 나무 같은 구조라, 요청이 끝나면 그 나무 전체가 취소된다.그런데 하필 그 시점에 LLM은 아직 답을 생성하는 중일 수 있다.저장도 후처리도 남아 있다.그냥 두면 생성 중이던 턴이 통째로 사라진다.사용자가 다시 들어와도 그 답이 없고, DB는 반쯤 쓰다 만 상태가 된다.사용자가 잠깐 끊었을 뿐인데, 진행 중이..

AI 2026.07.23

[비동기] SSE heartbeat 컨텍스트 누수 OTel 트레이스 깨짐

부제: 하트비트를 넣었더니 트레이스가 깨진 이야기챗봇은 답을 스트리밍으로 흘려보낸다.답이 길어지면 중간에 연결이 끊기지 않게, 주기적으로 빈 신호(하트비트)를 함께 보낸다.문제는 그 하트비트를 어떻게 끼워 넣었느냐였다.하트비트가 필요했다원래 구현은 이랬다.청크가 하나 올 때마다, 제너레이터의 다음 단계를 별도의 비동기 task로 띄웠다.하트비트 타이머와 다음 청크를 동시에 기다리려고 그렇게 쪼갠 것이다.겉보기엔 잘 돌았다.그런데 관측 도구에서 이상한 에러가 쏟아지기 시작했다."다른 컨텍스트에서 만들어진 토큰"트레이스를 남기는 라이브러리(Langfuse, 내부적으로 OpenTelemetry)가계속 "Token was created in a different Context"라는 에러를 냈다.원인은 컨텍스트였..

Infra 2026.07.10
728x90