인증 요청의 반복이 청크 오류의 결과일 수 있었다

AI Commons hotfix 기록에는 릴리스 뒤 일부 브라우저에서 무한 로딩이 생기고 GET /auth/me가 반복됐다고 적혀 있다. 그 기록의 원인 설명은 인증 API보다 앞선 정적 파일과 앱 재부팅을 연결한다. 캐시된 옛 HTML이 삭제된 청크를 요청하고, 청크 오류가 새로고침을 반복시키는 흐름이었다.

  1. 옛 HTML을 재사용

    기존 HTML이 이전 해시 이름의 JavaScript 청크를 참조한다.

  2. 없어진 청크 대신 HTML 응답

    존재하지 않는 파일 요청에 SPA fallback이 HTML 200을 주면 JavaScript의 MIME 오류가 발생할 수 있다.

  3. 오류에서 자동 새로고침

    앱이 다시 부팅하고 현재 사용자 조회도 다시 시작한다.

  4. 부팅 중 카운터 삭제

    재시도 횟수가 매번 0이 되어 두 번 제한이 작동하지 않는다.

청크 처리기는 이미 sessionStorage에 경로·횟수·시각을 저장했다. 하지만 bootstrap()과 ErrorBoundary의 mount가 이를 지웠다. 엔트리 번들이 실행됐다는 사실만으로 뒤에서 불러올 lazy 청크까지 정상이라고 판단한 것이 문제였다.

복구 여부를 모르는 부팅은 예산을 초기화할 시점이 아니다

변경은 부팅과 ErrorBoundary mount의 조기 초기화를 제거했다. 재시도 상태는 새로고침을 넘어 남고, 사용자가 수동 재시도를 선택할 때의 초기화는 유지한다. 처리기의 실제 조건은 다음과 같다.

if (parsed.path !== currentPath || now - parsed.time > 10000) {
  parsed.count = 0;
}
if (parsed.count < 2) {
  sessionStorage.setItem(STORAGE_KEY, JSON.stringify({
    count: parsed.count + 1,
    time: now,
    path: currentPath,
  }));
  window.location.reload();
  return true;
}

이 예산은 같은 경로에서 저장된 마지막 재시도 시각으로부터 10초가 넘지 않은 동안 두 번이다. 허용할 때마다 시각을 갱신하며, 경로가 달라지거나 10초가 초과하면 새 예산을 준다. 브라우저의 전체 세션에서 무조건 두 번만 새로고침하는 제한은 아니다. 정확히 10초인 경우도 초과 조건에 들어가지 않는다.

회귀 테스트는 같은 경로에서 true, true, false, 경로 변경 후 재허용, 10,001ms 뒤 초기화와 9,999ms 동안 유지하는 경우를 검사한다. 호출마다 상태를 지우면 열 번 모두 새로고침을 허용하는 반대 사례도 둔다. 테스트의 location.reload는 jsdom mock이다. 실제 브라우저의 캐시와 웹서버 fallback까지 재현한 검증은 아니다.

새 HTML을 건네는 시점과 옛 자산을 지우는 시점을 나눈다

재시도만 제한하면 오류의 반복은 줄여도 옛 문서가 참조하는 파일은 복구되지 않는다. 같은 hotfix는 HTML에 no-cache, must-revalidate를 지정하고 정적 자산에 장기 immutable 캐시를 설정했다. HTML은 저장을 금지하는 대신 재사용 전에 검증하도록 하고, 해시 이름으로 구분하는 자산은 오래 재사용하는 방향이다.

빌드는 별도 staging 디렉터리에서 수행한다. 기존 자산을 지우지 않고 새 자산과 루트 파일을 복사한 뒤, HTML을 임시 파일로 옮겨 마지막에 같은 파일시스템의 rename으로 교체한다. 이전 HTML을 가진 브라우저도 남아 있는 옛 청크를 받을 수 있도록 자산 수명을 문서 교체보다 길게 잡았다. 누적된 파일의 저장 공간은 늘어나며, 180일을 넘긴 수정 시각의 자산을 정리하는 단계가 있다.

다만 자산 복사 명령의 || true는 실패를 무시한다. HTML 파일 교체 자체의 원자성과 “새 HTML이 참조하는 모든 자산의 복사가 반드시 성공했다”는 보장은 다르다. 파일 배치 순서는 개선됐지만 배포 전체가 원자적인 것은 아니다.

없는 JS 요청을 진짜 404로 반환하는 선택 규칙은 .htaccess에서 주석 상태다. 실제 Apache 설정과 응답 헤더의 효과는 handler 단위 테스트로 확인할 수 없다. 이 사례에서 확인할 경계는 재시도 상태의 수명, 문서 캐시 정책, 참조 대상 자산의 보존이며, 셋을 각각 검사해야 배포 뒤의 반복 부팅을 설명할 수 있다.