콘텐츠로 이동
17.5k

임시 파일로 인한 디스크 사용량

일부 사용자는 opencodex 홈(기본값 ~/.opencodex)에서 재부팅할 때마다 늘어나는 responses-state.json.ocx.<pid>.<seq>.tmp 형식의 파일을 수 GB씩 발견했습니다.

opencodex는 프록시를 다시 시작해도 previous_response_id 체인이 이어지도록 연속 대화 캐시를 유지합니다. 스냅샷을 원자적으로 기록할 때 먼저 임시 파일에 내용을 쓰고 한 번에 실제 파일을 교체합니다. 기록 도중 충돌이 나도 반만 기록된 스냅샷이 남지 않는 이유입니다.

교체가 끝나면 보통 임시 파일을 즉시 삭제합니다. 두 단계 사이에 프로세스가 종료되면 임시 파일이 남습니다.

스냅샷은 덧붙이는 방식이 아니라 매번 전체를 다시 기록하므로 파일 하나가 최대 24 MB일 수 있습니다. 버려진 파일이 몇백 개만 쌓여도 공간을 빠르게 차지합니다.

이 파일은 영구 상태가 아니라 캐시입니다. 삭제하면 진행 중인 대화 체인이 문맥을 한 번 다시 보낼 수 있다는 점 외에는 손실이 없습니다. 설정, 자격 증명, 기록은 이 파일에 들어 있지 않습니다.

정리 기능은 이미 있었지만, 프록시가 연속 대화 캐시를 처음 불러올 때 한 번만 실행됐습니다. 이 시점은 해당 프로세스가 파일을 쓰기 전입니다. 여기서 두 문제가 생겼습니다.

프록시가 충돌 후 다시 시작되면 이전 프로세스가 방금 남긴 임시 파일을 보기에는 너무 일찍 정리했습니다. 현재 기록 중인 파일을 건드리지 않도록 15분 유예 기간이 있기 때문입니다. 이후에는 실행 내내 다시 검사하지 않아 재시작할 때마다 파일이 하나씩 늘었습니다.

더 큰 문제는 파일 소유 프로세스 ID가 아직 살아 있으면 정리 대상에서 제외했다는 점입니다. 재부팅 뒤 운영체제는 같은 프로세스 ID를 다시 할당하므로 오래된 파일을 실행 중인 프로세스의 파일로 영원히 오인할 수 있었습니다. 그래서 재부팅과 함께 파일이 늘어났습니다.

정리 작업은 시작할 때 한 번만 실행되는 대신 프록시의 일반 백그라운드 타이머에서 반복됩니다. 실행 중인 프록시가 버려진 파일을 직접 회수합니다. 현재 부팅 시각보다 오래된 파일에는 프로세스 ID 검사도 적용하지 않습니다. 실행 중인 프로세스가 그런 파일을 소유할 수 없기 때문입니다.

안전 규칙은 그대로입니다. 생성된 지 15분이 안 된 파일은 삭제하지 않으며, 프록시가 직접 기록 중인 파일도 삭제하지 않습니다.

기록에는 디바운스가 적용되며, 대기 시간은 마지막으로 실제 기록한 스냅샷의 크기를 기준으로 정합니다. 파일이 작을 때는 변경 후 약 2초 뒤에 다음 기록을 예약합니다. 파일이 24 MB 한도에 가까워지면 최대 30초까지 기다립니다. 따라서 캐시가 막 커졌다면 한 번은 짧은 대기 시간을 사용하고, 더 긴 주기는 그 다음 기록부터 적용됩니다. 이 프로세스가 같은 바이트를 같은 파일에 이미 썼고, 디스크의 파일도 일치하며, Windows 이외에서는 권한이 소유자 전용일 때만 기록을 건너뜁니다. 새 프로세스는 동일한 스냅샷도 한 번 다시 기록합니다. 프록시 밖에서 파일 내용이나 권한이 바뀌었다면 그대로 두지 않고 강화된 기록 경로로 다시 씁니다.

일반 백그라운드 주기마다 전체 원자적 다시 쓰기는 최대 한 번입니다. 기록 중에 연속 대화 캐시가 바뀌면 전체 스냅샷을 곧바로 다시 쓰지 않고 일반 지연 주기에 후속 기록을 하나 예약합니다. 정상 종료 시에는 진행 중인 요청이 배출된 뒤에도 제한된 재시도를 유지해 프로세스가 끝나기 전에 최종 스냅샷이 따라잡도록 합니다.

이렇게 캐시가 커져도 2초마다 전체 파일을 다시 직렬화하고 교체하는 대신 기록 빈도를 대체로 일정하게 유지합니다.

정상 종료 시에는 타이머를 기다리지 않고 즉시 기록합니다. 긴 대기 시간은 주로 강제 종료 시 가장 최근 연속 대화 항목을 잃을 수 있는 구간을 넓힙니다. 앞서 설명했듯 이 항목은 캐시입니다. 종료 시 기록도 디스크 쓰기이므로 다른 쓰기와 마찬가지로 실패할 수 있습니다. 디스크가 가득 찼거나 읽기 전용이면 같은 항목을 잃을 수 있습니다.

프록시가 실행 중이면 1~2분 안에 자동으로 회수됩니다.

파일이 가장 빠르게 쌓이는 경우처럼 프록시가 시작되지 않는다면, 명령줄에서 확인하고 회수하세요.

Terminal window
ocx doctor

“Response-state temp files” 섹션에서 회수 가능한 파일 수와 차지하는 공간을 알려줍니다. 보고만 하며 파일을 변경하지 않습니다.

실제로 삭제하려면 다음을 실행하세요.

Terminal window
ocx doctor --reclaim-response-temps

두 명령 모두 프록시 실행 없이 사용할 수 있습니다. 다른 프로세스가 잠근 파일은 강제로 삭제하지 않고 보고합니다. 다음 회수 때 다시 시도합니다. 프록시가 실행 중이면 자동으로, 아니면 이 명령을 다음에 실행할 때 시도합니다.

쌓인 파일이 너무 많아 한 번에 처리하지 못하면 남은 수를 알려주므로 명령을 다시 실행할 수 있습니다.

이 기능은 응답 상태 스냅샷의 임시 파일만 다룹니다. 이름이 비슷한 다른 구성 요소의 임시 파일은 건드리지 않습니다.