한 채널의 마켓 상품 팔만 건을 일괄로 연동 해제하는 작업이었다. 해제하면 channel_products 의 approval_status 와 link_status 두 플래그가 함께 붙는데 이 조합이면 다시 연동할 수 없으니 상태를 바꿔 줘야 한다는 이야기가 반복해서 나왔다.
Table of contents
Open Table of contents
문제 — 개발자 개입이라고 말한 근거
나도 그 단계는 개발자 개입이 필요하다고 말했다가 사실이 아니라는 지적을 받았다. 확인해 보니 운영자가 관리 화면에서 대상을 찾아 전송 버튼을 누르면 되는 일이었다.
내가 그렇게 말한 이유는 두 플래그가 붙어 있는 것을 보고 막혀 있다고 읽었기 때문이다. 화면에서 무엇을 할 수 있는지는 확인하지 않은 채로 상태 값만 보고 판단했다.
원인 — 잠금과 대기의 차이
그 상태 조합은 막힌 상태가 아니라 재등록을 기다리는 상태였다. 연동을 끊었으니 지금은 안 나가고 운영자가 다시 보내겠다고 하면 나간다.
잠긴 상태와 대기 상태는 데이터만 보면 같아 보이지만 사람이 무엇을 할 수 있느냐에서 갈린다. 운영자가 화면에서 할 수 있으면 그것은 개발자 개입이 필요한 자리가 아니다.
두 플래그가 막는 서로 다른 경로
여기서 핵심은 두 플래그를 같은 것으로 본 것이었다. approval_status 는 운영자가 화면에서 보내는 수동 전송을 막고 link_status 는 sync:products 스케줄러의 자동 재등록을 막는다.
자동 재등록 코드의 validate() 에서 link_status 를 보고 있었고 approval_status 는 그 자리에서 보지 않았다. 두 값이 서로 다른 경로를 막고 있었으므로 하나로 묶어 다룰 수 없었다.
주의 — 하나만 바꿨을 때 열리는 것
approval_status 를 정상으로 바꾸면 수동 전송이 열리지만 자동 재등록은 link_status 가 계속 막는다. 반대로 link_status 를 바꾸면 자동 재등록이 열려서 스케줄러가 팔만 건을 다시 올리기 시작한다.
게다가 setLinkStatus() 가 approval_status 를 자동으로 풀어 주는 구조라 link_status 를 건드리는 순간 두 가드가 함께 사라진다. 하나만 바꾸는 조작이 안전하지 않은 이유가 여기 있었다.
결론 — 안 해도 된다는 결론
두 가지 방법이 있었는데 계획대로 상태 전환 두 단계를 배치에 넣는 것과 연동 해제만 하고 상태는 그대로 두는 것이다. 뒤쪽을 골랐다. 이유는 두 플래그를 코드로 건드리는 순간 위에서 본 대로 가드 둘이 함께 사라져서다. 대신 운영자가 다시 팔고 싶은 상품을 화면에서 건별로 보류 해지해야 하는 것을 감수했다. 운영자가 보류를 해지하는 시점에만 재등록이 시작되는 원래 설계가 그대로 유지된다.
원래 계획에 있던 상태 전환 두 단계를 설계에서 뺐고 무엇을 더 해야 하는지 조사한 결과가 안 해도 된다는 것이었다. 대상 팔만 건의 products.sale_status 도 GROUP BY 로 세어 보니 대부분 이미 중지나 종료라 연동을 끊어도 매출에 영향이 없었다.
정리
- 두 상태 플래그가 서로 다른 경로를 막을 수 있다
approval_status는 수동 전송을 막고link_status는 자동 재등록을 막는다- 하나만 바꾸면 어느 쪽이 열리는지를 따로 봐야 한다
- 상태 변경 함수가 다른 플래그를 자동으로 풀어 줄 수 있다
- 잠긴 상태와 대기 상태는 데이터만 보면 같아 보인다
- 운영자가 화면에서 할 수 있으면 개발자 개입이 아니다
- 조사 결과가 안 해도 된다이면 설계에서 그 단계를 뺀다
- 플래그 이름이 아니라 그 값을 검사하는 코드를 찾는다