취소 대기로 남은 건들이 있었고 오래된 것은 열한 달째였다. 재수집을 돌리면 되살아나지 않겠느냐는 생각으로 시도하려다 멈추고 정상 흐름부터 그렸다.
Table of contents
Open Table of contents
세 단으로 나뉜 정상 흐름
정상일 때는 수집이 클레임 테이블에 대기 상태로 적재하고 스케줄러가 대기 건을 큐로 보내며 컨슈머가 외부 호출 뒤 성공으로 전환한다. 세 단이므로 정체 건이 어디서 멈췄는지와 재수집이 어디로 들어가는지를 각각 따져야 한다.
흐름을 그리지 않으면 재수집이라는 행위가 어느 단에 작용하는지 알 수 없다. 시도부터 하면 결과를 해석할 기준도 없다.
기존 레코드가 만나는 다른 분기
수집 코드를 보니 같은 조건의 기존 레코드가 있으면 신규 생성이 아니라 수정 분기로 들어갔다. 그런데 그 분기에서 상태를 되돌리는 부분이 주석 처리돼 있어 아무 값도 바뀌지 않는다.
즉 재수집을 돌려도 레코드는 그대로 남는다. 신규 건에만 작동하는 경로였고 정체 건은 정의상 신규가 아니다.
스케줄러가 집지 않는 상태
설령 무언가 바뀌었더라도 스케줄러는 대기 상태만 픽업한다. 정체 건들의 상태는 이미 성공이었는데 외부 호출은 됐고 후속 처리가 안 된 것들이었다.
두 사실을 합치면 재수집은 코드 경로상 무효이므로 돌려 봐야 시간만 쓴다. 게다가 돌렸는데 안 된다는 결과를 얻으면 엉뚱한 원인을 찾기 시작한다.
복구와 정리를 가르는 기준
복구 수단은 둘이었는데 하나는 상태를 대기로 되돌려 자동 재처리를 태우는 것이고 다른 하나는 상위 레코드를 수동으로 마감하는 것이다. 마켓에 아직 반영되지 않은 건은 전자이고 마켓에는 반영됐는데 우리 상태만 어긋난 건은 후자다.
이 구분은 우리 데이터만으로는 되지 않고 상대 쪽 상태를 봐야 갈린다. 열한 달 된 건들은 대부분 후자일 가능성이 높으므로 오래된 정체는 복구가 아니라 정리 대상인 경우가 많다.
주석으로 남은 코드가 남긴 것
이 조사에서 걸린 지점은 상태를 되돌리는 로직이 지워지지 않고 주석으로 남아 있다는 것이었다. 왜 껐는지는 어디에도 적혀 있지 않았다.
읽는 사람은 문제가 있어 끈 것인지 임시로 껐다 잊은 것인지 구분할 수 없다. 그래서 상태를 직접 되돌리는 조치도 왜 그 코드가 꺼졌는지 모른 채 같은 일을 하는 셈이 되므로 주석 처리한 코드에는 이유를 적거나 지우고 이력에 맡겨야 한다.
정리
- 복구를 시도하기 전에 정상 흐름을 그린다
- 재수집이 기존 레코드를 만나면 다른 분기로 간다
- 그 분기의 핵심이 주석 처리돼 있으면 아무 일도 없다
- 스케줄러가 특정 상태만 집으면 다른 상태는 영영 안 잡힌다
- 코드 경로상 무효인 시도는 하지 않는다
- 무효인 시도는 시간뿐 아니라 오진까지 부른다
- 오래된 정체는 복구가 아니라 정리 대상인 경우가 많다
- 주석 처리한 코드에는 왜 껐는지를 적는다