로컬에 한 번 쓰고 공개 주소에도 한 번 보내던 발행 절차가 있었다. 두 주소 뒤에 서로 다른 저장소가 있을 때와 같은 앱이 있을 때, 이 절차의 뜻은 달라진다. K-POP PULSE의 9월 운영 기록에서는 서빙 구성을 바꾼 뒤 두 경로가 같은 데이터베이스로 돌아오고 있었다.
같은 글 식별자로 다시 쓰려다 충돌하는 것만 문제가 아니었다. 로컬 쓰기가 실패해도 원격이 받아 줄 것이라는 옛 가정까지 남아 있었다. 나는 실제 수정 입력과 파일 갱신 결과를 읽으며, 운영 구성을 바꾸는 일이 호출 주소를 바꾸는 것보다 큰 작업이라는 점을 다시 보게 된다.
주소가 두 개라고 저장소도 두 개인 것은 아니다
이 프로젝트는 이전 구성에서 로컬 작업과 별도 원격 인스턴스의 관계를 고려한 발행 경로가 있었다. 이후 로컬 서빙과 Cloudflare Tunnel로 옮긴 운영 기록에서는 공개 주소가 같은 앱으로 연결된다. 겉으로 다른 주소를 사용해도 쓰기가 도착하는 대상은 같아질 수 있었다.
나는 이런 전환에서 주소 목록과 데이터 소유자의 관계를 함께 그려 보는 편이 좋다고 본다. 어떤 요청이 어떤 프로세스로 가고 그 프로세스는 어느 저장소를 쓰는가? 주소나 배포 이름만 다르다는 이유로 독립된 데이터가 있다고 가정하지 않는다.
중복 충돌은 잘못된 경로를 드러내는 신호였다
9월 26일 수정 기록에는 두 번째 발행이 같은 slug로 409 충돌을 일으킨다는 설명이 남아 있다. 이미 같은 저장소에 들어간 글을 다른 경로로 한 번 더 쓰려던 것이다. 이때 글 식별자를 바꾸어 재시도하면 경로의 문제를 중복 글로 바꿀 수 있다.
같은 요청을 안전하게 다시 실행해야 한다는 일반적인 요구와 불필요한 쓰기를 두 번 해야 한다는 것은 다르다. 나는 충돌 응답을 받으면 요청을 다시 보내기 전에 이미 쓰인 상태와 호출 경로부터 읽어야 한다고 본다. 재시도의 목적은 모호한 결과를 확인하는 것이지 반복 횟수를 늘리는 일이 아니다.
실패 뒤에도 성공처럼 끝나는 가정을 고쳤다
이전 절차에는 로컬이 실패해도 원격 경로가 받아 준다는 전제가 있었다. 두 경로가 같은 저장소를 향하게 된 뒤에는 로컬 실패가 실제 발행 없음으로 이어질 수 있었다. 당시 수정은 이 상태를 비정상 종료로 보고하도록 바꾸었다.
사용자에게 성공이라고 말하는 시점은 운영 구조와 맞아야 한다. 화면을 열 수 있다는 사실, 요청을 보냈다는 사실, 데이터가 저장되었다는 사실을 섞으면 다음 작업자가 복구해야 할 상태를 놓친다. 나는 실패를 드러내는 종료 코드도 프로그램의 중요한 결과물로 본다.
쓰기 한 번과 재시도할 자료를 함께 남겼다
수정된 코드에서는 우선 같은 발행 통로로 한 번 쓰고 실패하면 payload를 재시도 기록에 남기며 실패로 끝낸다. 별도 원격 인스턴스를 다시 두는 경우에만 원격 발행을 명시적으로 켜도록 했다. 기본 동작과 특정 구성을 위한 추가 동작을 나눈 것이다.
아래는 그 판단을 익명화한 의사코드다. 바로 실행할 수 있는 원본 구현은 아니며 저장·복구 함수를 구현해야 한다. 재시도 기록에 원고가 있다고 자동으로 재발행해도 되는 것은 아니다. 실제 상태와 현재 검토 기준을 읽은 뒤 어떤 작업을 다시 해야 할지 결정한다.
코드와 구현 살펴보기
판단을 보여 주는 의사코드. 당시 코드의 실행 가능한 복원본이 아니다.
# Explanatory pseudocode, not the historical publisher.
payload = build_reviewed_payload()
try:
persist_once(payload)
except Exception:
preserve_retry_material(payload)
return 3 # failure remains a failure
return 0구성 전환에서 지워야 할 옛 가정을 찾는다
저장소가 합쳐지면 두 번 쓰는 코드뿐 아니라 실패 허용, 백업 대상, 재시작 뒤 데이터의 수명도 다시 읽어야 한다. 운영 문서에도 더 이상 쓰지 않는 원격 백업·배포 절차를 구별한 기록이 있다. 주소 연결이 끝났다는 이유로 작업 설명서까지 현재 상태가 되는 것은 아니다.
나는 전환 검토에서 정상 경로와 실패 경로를 각각 그리기를 권한다. 정상일 때 어느 쓰기가 정본을 만들고 실패할 때 무엇이 남는지 적는다. 이후 예전 통로의 설정이 남아 있어도 뜻하지 않은 두 번째 쓰기가 생기지 않는지 확인한다.
기록의 수정과 현재 운영의 증명을 구별한다
이번 글에서는 9월의 실제 파일 수정 입력과 성공 응답, 운영 문서의 단일 쓰기 설명을 대조했다. 지금 원본 사이트의 모든 발행·재시도 경로를 새로 실행해 본 결과는 아니다. 제작 기록에 남은 선택과 다른 프로그램에 적용할 기준을 설명하는 범위다.
다른 홈페이지에 이 구조를 적용한다면 같은 글을 한 번 발행한 상태, 첫 쓰기 실패, 응답을 못 받은 상태, 별도 저장소가 있는 상태를 나눠 확인하면 좋다. 어떤 상태에서도 실패를 성공이라고 보고하거나 중복 글로 감추지 않는지가 중요한 확인이다.
- 주소별로 실제 도착하는 앱과 저장소를 확인했는가?
- 이미 쓰인 요청을 다시 보내기 전에 정본을 읽는가?
- 실패 응답과 종료 코드가 현재 구성의 뜻과 맞는가?
- 재시도할 자료와 현재 발행 상태를 다시 대조할 수 있는가?