Skip to content
isdnetworks
Go back

반증된 가설과 막힌 검증 경로

(수정됨)

한 채널에서 INVALID_OPTION 오류가 대량으로 나고 있었고 사례 하나를 보고 legacy_option_code 가 NULL 이라서 나는 것이라는 가설을 세웠다. 그 사례에서는 실제로 legacy_option_code 가 비어 있었으므로 그럴듯한 설명으로 보였다.

Table of contents

Open Table of contents

검증 — 결정적 표본으로 한 확인

가설을 검증하려고 GROUP BY seller_id 로 오류가 가장 많은 입점사를 골라 그 업체의 표본 상품을 같은 방법으로 확인했다. 그 컬럼에 값이 들어 있었고 option_code 도 정상으로 생성돼 있었는데 같은 INVALID_OPTION 이 그대로 재현됐다.

이미 그 컬럼의 복구가 끝난 구간도 COUNT(*) 로 확인했더니 3천 건이 넘는 오류가 여전히 잔존하고 있었다. 값이 있는데도 나고 복구했는데도 남는다는 두 관측이 같은 방향을 가리켰으므로 그 값이 비어서 나는 오류가 아니었다.

조치 — 명시적으로 폐기한 가설

가장 중요한 결정이 여기서 나왔다. 이 오류를 그 값을 채우면 해결되는 것으로 다루지 않기로 ISSUES.md 에 명시했다.

이것을 안 적으면 다음 사람이 또 복구 작업을 돌리고 그러고도 안 낫는 일이 반복된다. 틀린 가설은 조용히 버리는 것이 아니라 폐기했다고 적어야 다음에 되살아나지 않는다.

원인 — 유력해진 새 가설

관측을 다시 놓고 새 가설을 세웠다. 복구 작업 전후로 option_code 를 만드는 기준이 달라졌으므로 등록된 코드와 지금 보내는 코드가 다를 수 있다는 것이었다.

등록된 것과 보내는 것이 다르면 채널이 거부하는 것이 자연스럽다. 오류가 조회가 아니라 PUT /products/{id} 시점에 발생한다는 관측도 이 가설과 맞아떨어졌는데 수정할 때 코드를 보내기 때문이다.

주의 — 막힌 검증 경로

확인하려면 채널에 실제로 무엇이 등록됐는지를 봐야 했고 GET /products/{id} 를 불러 봤다. 응답에 options 목록 자체가 들어 있지 않아서 등록된 코드를 조회할 방법이 없었다.

두 가지 방법이 있었다. 새 가설을 전제로 코드를 다시 보내 보는 것과 억지로 결론을 내지 않고 적어 두는 것이다. 뒤쪽을 골랐다. 이유는 등록된 값을 모르는 채 보내면 맞아도 왜 맞았는지 모르고 틀리면 3천 건이 더 나빠질 수 있어서다. 대신 이 조사가 원인 확정 없이 끝나는 것을 감수했다. 그래서 세 줄로 적었다. 유력하지만 아직 검증되지 않은 가설이 무엇이고 확인하려면 등록된 값과 대조해야 하며 현재 조회 경로가 실패하므로 대체 조회 수단 확보가 선행 과제라는 것이다.

배경 — 못 푼 결과의 값어치

이렇게 적으면 다음 사람의 일이 명확해진다. 대체 조회 수단을 찾고 등록된 코드와 우리가 보내는 option_code 를 대조하면 되므로 원인 불명이 아니라 이것을 확인하면 된다는 형태가 된다.

이 조사의 결과가 못 풀었다는 것인데도 값어치가 있었다. 틀린 가설을 폐기하지 않았으면 3천여 건이 그대로인 채 복구 작업만 계속 돌았을 것이다. 가설을 세웠으면 유리한 표본이 아니라 결정적인 표본을 골라 반례를 적극적으로 찾아야 하고 이건 아니라고 확정하는 것도 진전이다.

정리


Share this post on:

Previous Post
직접 접속이 아니었던 구성
Next Post
상한을 산술로 계산한다