판매중지한 상품에 나흘 뒤 주문이 들어와 마켓에서 패널티가 붙었고 이의를 제기해야 하는 상황이었다. products.status 를 조회하니 나흘 전에 SUSPENDED 로 바뀐 것이 맞았다.
Table of contents
Open Table of contents
증상 — 멈춰 있던 연동 상태
channel_products 를 보니 status 가 ON_SALE 이었고 updated_at 이 중지한 날보다 한참 앞에서 멈춰 있었다. 우리 쪽에서 중지했는데 연동 쪽은 그 뒤로 아무것도 바뀌지 않은 상태였다.
멈춘 타임스탬프가 단서였고 그 뒤로 아무 일도 안 일어났다는 뜻이다. channel_jobs 이력을 보니 UPDATE 작업만 있고 SUSPEND 작업이 하나도 없었다.
원인 — 만들지 않는 경로
경로를 따라가니 ProductObserver 의 updated() 가 상위 상품 수정을 전파해 하위 상품의 status 를 SUSPENDED 로 바꾸고 UPDATE 작업을 만드는데 SUSPEND 작업은 만들지 않았다. Laravel 9 공식 문서대로 updated 이벤트는 기존 모델을 수정해 save() 를 부를 때 발생하므로 옵저버가 돈 것은 맞고 문제는 그 안에서 만드는 작업의 종류였다. 상태는 바뀌는데 밖으로 나가는 것이 없는 구조였다.
이것은 이 상품만의 문제가 아니라 이 경로로 중지된 상품 전부가 같은 상태다. 하위에서 직접 중지하면 정상이고 상위에서 수정으로 중지하면 안 나가는데 어느 경로로 중지했느냐에 따라 결과가 다르고 운영자는 그 차이를 모른다.
판단 기준 — 바뀐 확인 기준
이 조사로 규칙이 하나 생겼다. 판매중지가 마켓에 실제로 반영됐는지는 products.status 로 확인하면 안 된다. 두 가지 방법이 있었는데 이 상품만 SUSPEND 작업을 손으로 넣는 것과 ProductObserver 가 상태 전파 때 SUSPEND 작업도 만들게 고치고 같은 경로로 중지된 상품을 전수로 찾아 넣는 것이다. 뒤쪽을 골랐다. 이유는 이 경로로 중지된 상품 전부가 같은 상태라서다. 대신 전수 조회와 배포가 끝날 때까지 이의 제기가 며칠 늦어지는 것을 감수했다.
내부 상태는 우리 의도이고 channel_products.status 와 SUSPEND 작업의 존재가 실제 결과다. 반영 확인은 그 둘로 한다.
뒤집힌 판정
패널티 이의 건으로 돌아가면 처음 판정은 판매중지 후 주문이 들어왔으니 마켓 쪽 문제이거나 파트너 과실이라는 것이었다. 조사 후에는 우리 시스템이 중지를 안 보낸 시스템 이슈로 바뀌었다.
확인하지 않고 이의를 냈으면 근거가 틀렸을 것이다. 외부에 나가는 판단일수록 근거를 확인해야 하고 원인이 우리 쪽일 수 있다.
주의 — 나눠 적은 세 가지
조사 중에 이상한 것이 하나 더 나왔다. 이 상품이 신규 구조로 이관된 것은 맞는데 migration_log 와 product_histories 어디에도 기록이 없었고 channel_jobs.event 값에서만 확인됐다.
이것이 이 건만인지 전수 현상인지는 확인하지 못했고 그대로 적어 뒀다. 전수라면 이관 여부를 이력 테이블로 판별하는 다른 코드들이 전부 틀리게 된다. 한 건 조사에서 이 건의 원인과 부류와 별개 의문 셋이 나왔고 섞지 않고 나눠 적었다.
정리
- 내부 상태와 연동 상태가 다를 수 있다
- 상태는 우리 의도이고 연동은 실제 결과다
- 갱신 시각이 멈춰 있으면 그 뒤로 아무 일도 안 일어난 것이다
- 상태 변경과 연동 작업 생성이 같이 안 일어나는 경로가 있다
- 어느 경로로 조작했느냐에 따라 결과가 다르다
- 반영 확인은
channel_products.status와SUSPEND작업 존재로 한다 - 외부에 나가는 판단일수록 근거를 확인한다
- 조사에서 나온 것을 이 건과 부류와 별개 의문으로 나눠 적는다