콜드 캐시 모델 해석 버그
나는 회사 작업이랑 에이전트 도구 작업을 같이 한 날이었다.
회사에서는 새 코스 분류 도입의 진행 상황을 점검하고 다음 주 계획을 잡았다.
에이전트 도구에서는 두 가지 버그를 잡았다.
콜드 캐시가 에이전트에게 잘못된 모델을 주는 문제랑 폴백 플러그인의 SSE 무한 재시도 루프다.
첫 번째 버그는 미묘했다.
에이전트가 처음 실행될 때, 설정한 모델과 다른 모델을 할당받는 문제였다.
원인은 콜드 캐시였다.
처음 실행할 때는 모델 목록 캐시가 비어 있다.
그러니까 모델 ID를 해석하는 코드가 다른 경로로 빠진다.
그 경로는 디폴트 모델로 떨어지고 설정한 모델이랑 실제로 할당되는 모델이 어긋난다.
이게 왜 문제인가. 계획 에이전트들은 고성능 모델이 필요하다.
근데 콜드 캐시 폴백으로 디폴트 모델이 할당되면, 계획 품질이 떨어진다.
설정대로 안 돌아가니까. 해결은 9개 에이전트의 폴백 모델을 설정 파일에서 따로 빼는 거였다.
캐시 상태와 무관하게, 각 에이전트가 어떤 모델을 써야 하는지 명시적으로 고정한 거다.
캐시가 비어 있어도 올바른 모델로 떨어진다.
SSE 무한 재시도 루프
두 번째 버그는 어제 만든 폴백 플러그인에 있었다.
SSE 스트림이 끊어지면 재시도를 하는데, 이 재시도가 무한 루프에 빠졌다.
스트림이 연결되다가 끊어지면 재시도, 또 끊어지면 재시도. 이게 끝나지 않고 계속 반복된 거다.
해결은 재시도 횟수 제한을 두는 거였다.
몇 번까지만 재시도하고 그래도 안 되면 폴백으로 넘어간다.
무한히 재시도하는 건 의미가 없다.
계속 같은 이유로 실패할 테니까.
에러 분리
폴백 플러그인에서 에러 처리도 정리했다.
에러를 종류별로 분리해서 처리하는 거다.
핵심은 일시적 에러랑 영구적 에러를 구분하는 거다.
속도 제한이나 서버 과부하 같은 일시적 에러는 재시도하면 성공할 수 있다.
반면 인증 실패나 지원하지 않는 기능 같은 영구적 에러는 재시도해도 같은 결과가 나온다.
그러니까 바로 폴백으로 넘어가야 한다.
이 구분이 없으면 영구 에러에 재시도를 낭비한다.
지원하지 않는 기능을 계속 시도해봤자 안 된다.
빨리 다른 모델로 넘어가는 게 낫다.
대용량 컨텍스트 폴백
그리고 대용량 컨텍스트 폴백도 추가했다.
에이전트가 작업하다가 컨텍스트가 일정 비율을 넘으면, 컨텍스트가 더 큰 모델로 전환한다.
큰 모델이 작업을 끝내면 원래 모델로 돌아온다.
이건 어제 만든 기능의 연장이다.
컨텍스트가 찼다고 작업이 멈추면 안 된다.
큰 모델로 넘어가서라도 작업을 이어가는 게 낫다.
회사 작업 진행
회사 쪽에서는 새 코스 분류 도입 작업을 점검했다.
지난주에 첫 단계를 구현했다.
코스 분류 옵션 추가, 기본값 설정, 커리큘럼 바인딩, 제품 유형 필터링. 이걸로 코스 생성 모달이랑 기본 정보 탭에서 새 코스 종류를 선택할 수 있게 됐다.
이번주에는 2주차 범위를 정리했다.
파트 완료율, 순차 수강 잠금, 수료 정책 분기. 이게 다음에 구현할 단계다.
순차 수강은 학생이 이전 파트를 완료해야 다음 파트가 열리는 기능이다.
새 코스 종류에 이 기능을 확장하는 게 핵심이다.
이 작업은 전체 8개 단계로 나뉘어 있다. 지금은 그중 앞부분을 하고 있다.
코스 분류 추가로 시작해서, 수강 설정, 학생 화면, 수료 기준, 약관 분기까지 이어진다.
이날은 진행 상황을 점검하고 다음 계획을 잡은 단계였다.
마무리
콜드 캐시 버그가 흥미로웠다.
“처음 실행할 때만” 발생하는 버그는 잡기 어렵다.
두 번째 실행부터는 캐시가 있으니까 정상 동작한다.
그러니까 버그가 있다는 걸 알아채기 어렵다.
콜드 캐시 버그를 잡는 핵심은 캐시 상태와 무관하게 동작하도록 만드는 거다.
캐시가 있든 없든 같은 결과가 나와야 한다.
폴백 모델을 명시적으로 고정하니까, 캐시 상태에 의존하지 않게 됐다.
그리고 SSE 무한 재시도도 중요한 교훈이다.
재시도에는 항상 횟수 제한이 있어야 한다.
무한 재시도는 결국 무한 루프로 이어진다.
몇 번까지만 시도하고 그 이후에는 다른 전략으로 넘어가는 게 안전하다.