새 기능 하나 없이 일주일을 유지보수에 썼다

일주일 커밋에 새 기능이 하나도 없었다

7월 마지막 주에 뭘 했는지 목록으로 뽑아봤다. 증분 크롤러가 멈추던 문제 수정, 상세 스펙 추출 방식 변경, 푸시 알림 리텐션 개편, 푸시 발송 멈춤과 통계 불일치 수정. 앱 화면에 새로 생긴 메뉴는 없었다. 스토어 업데이트 설명에 적을 만한 한 줄도 없었다.

혼자 만들면 이 상태가 계속 걸린다. 새 기능을 안 붙이면 제자리인 것 같다. 그런데 주가 끝나고 보니 손댄 코드는 전부 이미 몇 달째 돌아가던 것들이었다. 정확히는, 돌아가고 있다고 믿었던 것들이었다.

고장은 예외로 오지 않았다

증분 크롤러는 첫 카테고리만 보고 멈춰 있었다. 프로세스는 살아 있었고, 로그에 에러가 없었고, 스케줄은 정상으로 찍혔다. 푸시도 비슷했다. 발송이 중간에 멈췄는데 통계 숫자는 그럴듯하게 남아 있었다.

둘의 공통점은 죽었다는 신호를 안 보냈다는 거였다. 크래시가 나면 오히려 빨리 안다. 조용히 절반만 일하는 쪽이 훨씬 오래 간다. 그 주에 얻은 건 기능을 만들 때 그게 지금 제대로 도는지 확인할 방법을 같이 만들어두는 편이 싸게 먹힌다는 감각이었다.

뭘 먼저 고칠지 정한 기준

네 건을 한꺼번에 볼 수는 없어서 순서를 정해야 했다. 쓴 질문은 세 개였다.

질문 크롤러 멈춤 푸시 멈춤
조용히 실패하는가 그렇다 그렇다
지난 데이터를 되돌릴 수 있는가 아니다. 안 긁은 구간은 공백으로 남는다 그렇다. 다시 보내면 된다
사용자가 바로 아는가 늦게 안다 안 오면 바로 안다

되돌릴 수 없는 쪽을 먼저 잡았다. 크롤러가 못 본 기간은 나중에 고쳐도 그 시점의 데이터가 돌아오지 않는다. 푸시는 고친 다음 다시 보내면 되는 일이었다. 사용자가 빨리 눈치채는 문제부터 손대고 싶은 마음이 컸는데, 그건 급한 것과 중요한 것을 헷갈린 거였다.

새 기능처럼 보였던 유지보수

같은 주에 붙인 두 가지는 겉보기엔 신규 기능이었다. 하나는 푸시 헤드라인 스코어링 엔진과 개봉률 트래킹. 다른 하나는 상세 스펙을 실측·소재·세탁까지 직접 뽑아내고 신상 여부를 판정하는 작업이었다.

둘 다 없던 걸 새로 만든 게 아니라, 있던 게 제 역할을 못 해서 만든 거였다. 푸시는 계속 나가고 있었지만 어떤 문장이 열리는지 몰랐다. 목록만 긁어서는 이게 신상인지 아닌지 판단할 근거 자체가 없었다. 기능이 있는 것과 쓸모가 있는 것은 다른 문제였다.

남은 이야기

한 주를 통째로 유지보수에 쓴 게 맞는 판단이었는지는 아직 잘 모르겠다. 이런 주가 몇 번 더 반복되면 그때는 설계를 의심해야 할 것 같은데, 그 선이 어디인지는 더 봐야 한다.

다만 순서를 정할 때 쓴 질문은 다음에도 그대로 쓸 생각이다. 조용히 실패하는가, 되돌릴 수 있는가, 사용자가 아는가. 셋 중 앞의 둘이 나쁜 쪽이면 눈에 안 보여도 먼저 고치는 게 맞았다. 혼자 하면 급한 것부터 손이 가는데, 급한 건 대체로 이미 알려진 문제고 알려진 문제는 최소한 더 나빠지지는 않는다.

새 기능 하나 없이 일주일을 유지보수에 썼다 · peppercode 개발 노트