누구에게 도움: 결과를 파일로 저장하는 배치 스크립트를 만들어서 반복 실행하는 사람. “같은 스크립트를 두 번 돌렸을 뿐인데 데이터가 사라지는” 사고를 예방하고 싶은 사람.
Before
전날(Day 13) 후보 회사 스크리닝 스크립트를 돌려서 577개짜리 결과 파일을 힘들게 모아뒀다. 다음날(Day 15), 이 스크립트에 “연속 실패하면 알아서 멈추는 안전장치(회로차단기)“를 추가하고서, 그게 진짜 작동하는지 테스트하려고 스크립트를 다시 실행했다.
어떻게 했나
1) 일부러 “고장난 상황”에서 테스트했다
그날은 마침 API 접속이 막혀있는 상태였다. “이런 상황에서 스크립트가 무한정 매달리지 않고 잘 멈추는지” 확인하려고 일부러 그 상태 그대로 실행했다.
node agent/bulk-screen.mjs
2) 회로차단기는 완벽하게 작동했다
연속 8번 실패하자 스크립트가 알아서 멈췄다. 목표했던 대로였다.
⚠️ 연속 8회 실패 — API가 막힌 것으로 판단해 회로차단기를 작동합니다.
3) 그런데 결과 파일을 열어보니 문제가 있었다
python3 -c "
import json
d = json.load(open('agent/data/bulk-screen-results.json'))
print('total_candidates:', d.get('total_candidates'))
"
total_candidates: 0
577개였던 결과가 0개로 바뀌어 있었다. 이번 실행은 아무것도 못 가져왔으니 결과가 0개인 게 당연한데, 문제는 스크립트가 “이번 결과(0개)“를 예전 파일 위에 그냥 덮어써버렸다는 것이었다. 어제 힘들게 모은 577개가 그렇게 사라졌다.
막힘 → 해결
- 막힘: 스크립트를 “다시 실행”하는 게 이렇게 위험한 일인 줄 몰랐다. 결과 저장 로직에 “이번 게 더 나은지” 체크가 전혀 없었다.
- 해결: 저장하기 직전에 이전 파일과 비교하는 코드를 넣었다.
if (totalCandidates < previousTotal) {
// 이번 결과가 더 적으면 원본은 그대로 두고, 별도 파일로만 저장
const partialPath = outPath.replace(".json", `-partial-${Date.now()}.json`);
writeFileSync(partialPath, JSON.stringify(result, null, 2));
} else {
// 같거나 더 많을 때만 진짜로 덮어씀
writeFileSync(outPath, JSON.stringify(result, null, 2));
}
After
- 다행히 완전히 다 잃진 않았다. 그 전날 만들어둔 “상위 30개 후보” 파일은 별도 파일이라 무사했다.
- 원본 577개 상세 리스트는 결국 못 살렸지만, API가 복구되면 스크립트를 다시 돌려서 재생성할 수 있다는 것도 확인했다 (업종코드는 매일 바뀌는 데이터가 아니라서).
- 지금부터는 같은 스크립트를 몇 번을 다시 돌려도, “이전보다 나쁜 결과”가 원본을 덮어쓰는 일은 없다.
배운 것 / 재사용 자산
결과를 파일로 저장하는 자동화 스크립트를 짤 때 기본으로 넣을 것
- 저장하기 전에 “기존 파일이 있다면, 이번 결과와 비교”하는 코드를 먼저 넣는다.
- 비교 기준은 단순해도 괜찮다 (예: 개수). 완벽한 판단이 아니어도, “숫자가 갑자기 확 줄면 뭔가 잘못됐다”는 신호로 충분히 유용하다.
- 이번이 더 나쁘면 원본을 바꾸지 말고 타임스탬프 붙은 별도 파일로 저장해서, 사람이 나중에 판단할 수 있게 남겨둔다.
- 이 판단 기준(개수)에는 한계가 있다는 것도 인지한다 — 개수는 같은데 내용이 틀렸거나, 정당한 이유로 개수가 줄어든 경우는 이 장치가 못 잡는다. 그래도 “아무 장치가 없는 것”보다는 훨씬 안전하다.
가장 큰 교훈은: “테스트로 한 번 더 돌려보는 것”조차 데이터를 망가뜨릴 수 있다는 걸 몸으로 겪었다는 것. 자동화 스크립트는 편리한 만큼, 안전장치 없이 쓰면 그만큼 빠르게 실수도 커진다.