저장에 실패했으니 임시파일을 정리하면 된다고 생각하기 쉽다. 하지만 어느 파일을 이번 시도가 만들었는지 모르면 정리 자체가 다른 작업을 건드릴 수 있다. 실제 기록 저장 오류의 재현과 수정 내용을 읽고, 작은 합성 저장 모듈로 핵심 경계를 다시 확인했다.
파일을 쓴 뒤에도 실패할 수 있다
원래 저장은 임시파일 작성 뒤 문맥을 다시 확인하고 목적지 이름으로 바꾼다. 그 사이 사용자가 작업을 취소하거나 문맥이 바뀔 수 있고 실제 이름 변경이 실패할 수도 있다. 기존 기록을 바로 덮지 않는 구조는 좋지만 실패한 임시파일의 책임도 남는다. 저장 성공과 정리 완료는 다른 질문이다.
개발 기록에는 수정 전 코드에서 문맥 확인 예외와 실제 이름 변경 실패, 잘못된 key의 생성 순서를 확인한 자료가 있다. 원래 구현은 Node 파일 저널이다. 이번 공유 코드는 Python의 작은 합성 레코드이며 실제 브라우저 영수증과 계정, 탭 정보는 넣지 않았다.
생성에 성공했을 때만 내 파일이라고 했다
새 save는 임시파일을 배타적으로 연다. 같은 이름이 이미 있으면 생성은 실패하고 그 파일을 내 소유로 표시하지 않는다. created는 실제 생성에 성공한 뒤에만 참이 된다. 실패 처리에서는 created가 참인 그 한 파일만 지운다. 폴더 전체의 tmp 확장자를 훑어 지우는 정리는 없다.
테스트에서는 임시 이름이 충돌하는 조건을 만들고 원래 파일의 바이트가 그대로인지 확인했다. 다른 작업의 unrelated.tmp도 남겨 두었다. 이름이 비슷하다는 이유와 확장자가 같다는 이유는 소유 근거가 아니기 때문이다. 정리를 하기 전에 무엇을 만들었는지 기록해야 한다는 작은 계약이다.
검증은 임시파일보다 먼저, 문맥 확인은 다시 했다
key와 레코드 필드는 파일 생성 전에 검사한다. 허용한 두 필드 외의 값과 경로처럼 쓸 수 있는 key는 거절한다. 호출자가 명시한 기존 신뢰 폴더 안에서만 실험한다. 임시파일 작성·flush·sync·닫기 뒤에는 check를 다시 호출하고 통과했을 때만 목적지를 바꾼다.
문맥이 바뀌면 이전 목적지 파일은 그대로 남고 이번 임시파일만 사라진다. 다만 check는 호출자가 제공하는 함수이며 실제 사용자와 권한을 인증하는 구현은 아니다. 신뢰 폴더의 상위 경로를 공격자가 바꾸는 환경과 서버 접근 통제도 이 예제가 해결하지 않는다. 작은 파일 저장의 전제를 분명히 했다.
실제 이름 변경 실패를 따로 만들었다
합성 시험은 목적지 이름에 디렉터리를 미리 만들어 실제 파일 교체가 실패하게 했다. 다른 peer 기록도 함께 저장해 두고 오류 후 목적지 디렉터리와 peer 바이트가 보존되는지 확인한다. 함수가 예외를 냈다는 사실만으로 기존 자료가 안전하다고 추정하지 않고 남은 파일을 다시 읽었다.
공유 모듈의 테스트 12개는 실제 로컬 파일을 사용했다. 소스 폴더와 ZIP을 새로 푼 폴더에서 각각 통과했다. 이는 이번에 실행한 합성 파일 검수이고, 원래 개발 보고서의 회귀 숫자와는 다르다. 실제 고객의 저장 폴더와 운영 프로그램은 시험 대상으로 사용하지 않았다.
정리 실패도 원래 오류를 지우지 않는다
저장 실패 뒤 임시파일 삭제도 실패할 수 있다. 새 예제는 원래 오류와 정리 오류를 ExceptionGroup에 함께 남긴다. 정리 예외 하나가 앞의 취소와 교체 실패를 가리지 않게 하려는 선택이다. 이 경우 임시파일이 남을 수 있음을 숨기지 않고 호출자가 확인할 근거를 제공한다.
강제 종료와 전원 차단까지 자동으로 정리한다고 보장하지 않는다. 디렉터리 동기화와 모든 파일 시스템의 내구성, 동시 작성 충돌 해결도 구현하지 않았다. 파일에 sync를 했다는 사실을 모든 장애에서 마지막 기록이 살아남는다는 약속으로 넓히지 않았다. 운영의 복구 정책은 별도로 필요하다.
작은 파일 계약을 공유하는 이유
기존 SQLite 원자 처리 모듈은 데이터베이스 안의 기록 관계를 다뤘다. 이번에는 파일 이름을 바꾸는 경계와 임시파일 소유를 다룬다. 같은 저장이라는 단어 때문에 서로의 보장을 빌리지 않는다. 아래 새 모듈에서 전체 코드와 실제 실행 기록, 테스트와 ZIP을 확인할 수 있다.
웹페이지의 선택기는 저장된 결과를 읽으며 방문자의 파일을 만들거나 지우지 않는다. 나는 저장 오류를 없앴다는 큰 문장보다 어떤 실패에서 무엇이 보존되고 어떤 파일만 정리하는지 설명할 수 있는 코드를 남기고 싶었다. 다른 작업에 적용할 때도 먼저 폴더의 신뢰와 동시 작성 정책을 정해야 한다.