재연동 작업에서 legacy_option_id 를 비워야 하는지 확인해야 했고 한 채널에 대해 필요 없다는 결론을 냈다. 그 결론의 근거가 channels/<이름>/ 디렉터리에서 grep 이 0건이었다는 것뿐이라는 지적을 받았다.
Table of contents
Open Table of contents
문제 — 섞여 있던 두 질문
지적은 그 채널이 신규 시스템을 경유하는데 그 신규 시스템 안에서도 그 값을 안 보는지 확인했느냐는 것이었다. 여기서 물음이 둘로 갈려 있다는 것을 알았다.
하나는 이 채널의 등록 처리가 어느 시스템을 경유하느냐이고 다른 하나는 그 경로 어디에서도 legacy_option_id 를 참조하지 않느냐다. 내가 답한 것은 채널 디렉터리에 없다는 사실뿐이라 둘 중 어느 쪽도 아니었다.
원인 — 마지막 한 칸만 본 검색
실제 경로를 따라가 봤다. RegisterJob 에서 ChannelHub 를 거쳐 ProductService::register() 와 신규 시스템 위임을 지나 최종 엔드포인트에 닿았다. 각 계층에 그 값을 보는 코드가 있을 수 있는 구조였다.
채널 디렉터리만 본 것은 그 경로의 마지막 한 칸만 본 것이다. 경유하는 계층을 먼저 그리지 않으면 어디를 봐야 하는지 자체가 정해지지 않는다.
가변 필드가 넓히는 사용처
또 하나는 그 값이 담기는 public $legacyOptionId 가 readonly 가 아니라 가변으로 선언돼 있다는 점이었다. 즉 런타임에 상류나 다른 클라이언트가 그 값을 덮어쓸 수 있다.
다른 채널의 처리가 그 필드를 채우고 공통 경로를 지나면서 값이 쓰일 수 있다. 그래서 선언 위치로 사용처를 한정할 수 없다. 이 성질 때문에 호출부 전수 확인이 필요했다.
검증 — 전수 호출부가 만든 근거
두 가지 방법이 있었는데 채널 디렉터리 검색 결과에 경유 시스템 디렉터리를 하나 더 보태는 것과 저장소 전체에서 setLegacyOptionId( 호출부를 열거하는 것이다. 뒤쪽을 골랐다. 이유는 가변 필드라 선언 위치로 사용처를 한정할 수 없어서다. 대신 나온 곳을 하나씩 열어 읽는 시간을 감수했다. grep -rn 으로 열거하니 정확히 열 곳이었고 다섯 채널에 두 곳씩 나뉘어 있었다. 문제의 채널은 그 열 곳 어디에도 없었다.
결론은 처음과 같았지만 근거가 달라졌다. 디렉터리에 없다가 아니라 전체가 열 곳이고 그중에 없다가 됐다. 그 채널은 옛 식별자 체계를 거치지 않고 product_options.id 를 그대로 쓰고 있었으므로 처리가 필요 없는 것이 맞았다.
결론 — 원래 물음에 없던 답
전수로 보고 나니 원래 묻지 않았던 사실이 나왔는데 나머지 다섯 채널에는 그 처리가 반드시 필요하다는 것이었다. product_options 가운데 상당한 비율이 실제로 legacy_option_id 를 갖고 있었다.
좁은 범위의 0건은 무엇을 뜻하는지 알 수 없다. 정말 안 쓰는 것인지 다른 이름으로 부르는 것인지 상류에서 채워지는 것인지 구분되지 않는다. 전체를 열거한 뒤의 0건만 반례를 배제한다.
정리
- 경유한다와 참조한다는 서로 다른 질문이다
- 경유 계층을 먼저 그려야 어디를 볼지가 정해진다
- 좁은 디렉터리 검색은 경로의 마지막 한 칸만 본다
readonly가 아닌 필드는 선언 위치로 사용처를 한정할 수 없다- 호출부를
grep -rn으로 저장소 전체에서 열거한다 - 결론이 같아도 근거가 다르면 다른 결론이다
- 전수로 보면 원래 물음에 없던 답이 나온다
- 좁은 범위의 0건은 뜻을 알 수 없다