카테고리 데이터가 오래돼서 갱신해야 했다. 배치 커맨드가 있을 것 같아 찾았다.
Table of contents
Open Table of contents
상황 — 갱신할 커맨드를 찾았다
app/Console/Commands/ 아래를 훑었다.
ls app/Console/Commands/
하나가 눈에 띄었다.
DownloadCategory.php
DownloadCategory 라는 이름만 보면 카테고리를 받아 오는 것으로 읽힌다.
이대로 돌리면 끝날 일로 보였고 이름이 맞으니 안을 안 열어 보고 실행할 뻔했다.
원인 — 이름이 맞아 보이던 것
열어 보니 다루는 대상이 달랐다.
class DownloadCategory extends Command
{
// 특정 연동사 카테고리만 처리
}
DownloadCategory 는 우리가 갱신하려는 채널이 아니라 다른 연동사 전용이었다.
그대로 돌렸으면 엉뚱한 채널의 자료를 건드릴 뻔했고 이름이 맞을수록 안을 안 보게 되니 위험이 더 컸다.
전수로 찾으니 없었다
다른 것이 있는지 시그니처를 전부 훑었다.
grep -rn "protected \$signature" app/Console/Commands/ | sort
signature 를 전부 뽑아 봐도 카테고리를 갱신하는 커맨드가 아예 없었다.
없는 것을 이름으로 찾고 있었던 셈이라 애초에 나올 리가 없었고 전수로 훑고 나서야 그 사실이 확정됐다.
커맨드가 없으면 다른 경로가 있을 것으로 보고 routes/ 를 봤다.
grep -rn "categor" routes/
관리 API 쪽 라우트에서 하나가 나왔다.
GET /api/categorys/get-distribution-categorys?channel=...
get-distribution-categorys 는 이름만 보면 조회로 읽혀서 이것이 맞는지 확신할 수 없었다.
조치 — 반드시 거치는 지점에서 역추적
이름을 근거로 삼는 검색은 그 이름이 정확할 때만 작동한다.
[이름으로 찾기] 이름이 맞아야 찾아짐
[필수 지점에서 역추적] 이름과 무관
방향을 바꿔서 broker 쪽의 반드시 지나가는 자리부터 잡았다.
① 브로커에서 외부 카테고리를 받는 함수를 찾음
getSourceCategoriesReq()
② 그 함수를 호출하는 곳을 찾음
grep -rn "getSourceCategoriesReq" app/
③ 컨트롤러에 도달
카테고리를 받으려면 getSourceCategoriesReq 를 안 거칠 수 없다.
이름이 무엇이든 그 자리를 지나야 하므로 grep 으로 호출자를 찾아 올라가면 경로가 잡힌다. 외부 호출이 그런 지점이 되는 경우가 많았다.
주의 — 조회처럼 보이던 이름
역추적으로 닿은 컨트롤러를 열어 봤다.
public function getDistributionCategorys(Request $request)
{
$broker = ...;
$categories = $broker->getSourceCategoriesReq();
// 마스터 테이블 갱신
}
getDistributionCategorys 는 외부에서 받아 우리 표를 갱신하는 동작이었다.
[이름] get-distribution-categorys — 가져오기
[동작] 가져와서 저장
get 으로 시작하는데 쓰기 동작이다.
이름과 동작이 어긋나 있으니 이름으로 찾아서는 영영 못 찾는 것이 당연했다. 앞의 커맨드와 이쪽이 서로 반대 방향으로 어긋나 있어서 두 번 헷갈린 셈이다.
비교 — 혼동하기 쉬운 이웃
같은 영역에 비슷한 것이 하나 더 있었다.
POST /distribution/category/update
category/update 가 오히려 갱신처럼 보이는데 실제로는 매핑 수정이었다.
[매핑 수정] 우리 카테고리 ↔ 외부 카테고리 연결
[마스터 동기화] 외부 카테고리 목록 자체를 받아옴
매핑 수정 과 마스터 동기화 는 하는 일이 다르다.
혼동해서 category/update 를 부르면 매핑만 바뀌고 마스터는 그대로 남는다. HTTP 오류는 안 나고 갱신했는데 여전히 옛 카테고리가 보이는 상태가 된다.
그래서 기록에 get-distribution-categorys 와 category/update 를 같이 적었다. 맞는 것만 적으면 다음 사람이 또 헷갈리므로 틀리기 쉬운 것을 나란히 적어 두는 편이 낫다.
Commands/ 에 해당 커맨드가 없는 것 자체도 남겨 뒀다. 사람이 눌러야 도는 구조라 아무도 안 누르면 계속 낡고 이번에 찾은 것도 그래서였다.
정리
- 이름이 맞아 보이는 커맨드가 다른 대상 전용이었다
- 이름이 맞을수록 안을 안 보게 되니 위험이 더 크다
- 전수로 찾고 나서야 없다는 것이 확정된다
- 이름으로 못 찾으면 반드시 거치는 지점에서 역추적한다
- 외부 호출 함수가 그런 지점이 된다
- 이름이 조회처럼 보이는데 갱신인 경우가 있다
- 이름 기반 검색은 이름이 정확할 때만 작동한다
- 이름이 비슷한 이웃을 잘못 부르면 아무 일도 안 일어난 것처럼 보인다
- 오류가 안 나므로 갱신됐다고 믿고 넘어간다
- 기록에 맞는 것과 틀리기 쉬운 것을 같이 적는다
- 사람이 눌러야 도는 구조는 아무도 안 누르면 계속 낡는다