생성 요청 타임아웃을 폴링으로 우회
목차
리포트와 티저 생성 기능이 Cloudflare의 100초 제한에 자주 걸리는 바람에, 사용자들이 페이지를 나가거나 새로고침을 하는 문제가 있었다. 이번엔 그걸 비동기 폴링으로 전환했다. 동시에 day카드 애니메이션 충돌도 정리했고, 대운 영문표기도 개선했다.
장시간 작업과 서버 제한의 딜레마
우리 서비스가 Cloudflare 워커 환경에서 구동되고 있는데, 이 환경은 한 요청에 100초라는 상한이 있다. 리포트나 티저를 생성하는 작업은 계산이 많아서 가끔 이 시간을 초과했다.
문제는 사용자 경험이었다. 요청을 보내고 응답을 기다리다가, 100초가 지나면 그냥 에러가 떨어진다. 사용자는 "뭔가 실패했나?" 정도로 인지하고, 페이지를 새로고침하거나 나갔다 다시 들어온다. 이건 신뢰도에 좋지 않다.
| 상황 | 기존 방식 | 문제점 |
|---|---|---|
| 리포트/티저 생성 요청 | 동기 대기 (100초 제한) | 타임아웃 → 에러 응답 |
| 사용자 경험 | 응답을 기다림 | 혼동, 재시도, 신뢰 하락 |
근본 원인은 API 라우트 설계였다. "요청 → 즉시 결과 반환" 방식인데, 생성 작업은 AI 모델 호출이나 DB 쿼리가 연쇄적으로 일어나면서 자연스레 시간이 걸린다.
202 Accepted + 폴링으로 재설계
HTTP 202는 "Accepted"를 뜻한다. 요청을 받아들였지만 아직 처리 중이라는 의미다. 이걸 활용해 API를 다시 설계했다.
새로운 흐름:
- 생성 요청 → API는 즉시 202 + 작업 ID 반환 (100초 제한 회피)
- 프론트엔드가 폴링 시작 (작업 ID로 상태 확인)
- 백엔드는 별도 큐에서 생성 작업 진행
- 완료되면 폴링 응답에 결과 담아 반환
초기 응답이 100초 안에 끝나므로 타임아웃이 없다. 백엔드는 더 느슨한 제약 하에서 작업을 마칠 수 있다.
src/app/api/reading/[uid]/report/route.ts와 src/app/api/reading/[uid]/teaser/route.ts에 이 로직을 구현했다. 두 라우트는 202 상태와 함께 작업 ID를 즉시 반환하고, 쿼리 파라미터를 통해 상태를 조회할 수 있게 개선했다. 프론트엔드의 src/app/r/[uid]/page.tsx와 src/app/r/[uid]/reading-panel.tsx에는 폴링 로직을 추가했다.
폴링 인터벌을 몇 초로 잡을지는 팀과 논의했다. 너무 자주하면 요청 부하가, 너무 드물면 사용자가 답답함을 느낀다. 리포트 생성 시간 분포를 보고 1~2초 정도로 튜닝했다.
day카드 애니메이션 충돌 해결
day카드의 fade-up 애니메이션과 glow 효과가 동시에 적용되면서 겹쳐 보이는 문제가 있었다.
원인은 CSS의 우선순위와 타이밍이었다. src/app/globals.css에서 fade-up 애니메이션이 transform을 주는데, glow 클래스의 box-shadow와 opacity가 동시에 변하면서 깜빡거렸다.
해결책은 animation-timing-function을 맞춰주고 레이어링을 명확히 하는 것이었다. 작지만 사용자가 보는 부드러움에 큰 영향을 준다.
대운 영문표기 정리
마지막으로 대운(大運)의 영문 표기를 다듬었다. 기존에는 단순 번역 수준이었는데, 한국 점술 체계의 정확성을 담으면서도 국제 사용자가 이해할 수 있게 일관성 있게 표기했다.
기술보다는 도메인 언어와 국제화 관련이지만, 사용자 신뢰도에 영향을 미친다.
회고: 혼합 커밋과 엣지 케이스
이번 작업은 아키텍처(202 폴링), UI/CSS(애니메이션), 콘텐츠(다국어) 세 성격을 담았다.
한 번에 여러 이슈를 닫을 수 있어서 좋지만, 리뷰 범위가 컸다. 다음엔 이런 혼합 커밋을 나눌지는 상황에 따라 다르겠지만, 최소한 커밋 메시지에 각 파트를 명확히 나열하는 게 팀의 이해를 돕는다.
202 패턴 같은 아키텍처 변경은 단순해 보이지만, 실제로는 폴링 실패, 중복 요청, 부분 완료 같은 엣지 케이스가 있다. 이런 부분까지 제대로 챙기려면 기본 구현 이상의 신경이 필요하다.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.