Skip to content
isdnetworks
Go back

확인하려고 넣은 조건이 코드에 남았다

동기화가 안 되는 상품이 있어서 원인을 찾으려고 MySQL 조회에 조건을 하나 넣었다.

$rows = $this->db->where('status', 'normal')->get('product')->result();

정상 상품만 보려고 넣은 것이었는데 원인을 찾고 나서 그 줄을 안 지웠다.

Table of contents

Open Table of contents

조사용이 로직이 됐다

한 달쯤 뒤에 판매 중지 상품이 동기화가 안 된다는 문의가 왔다. 당연했고 status = 'normal' 만 대상이니 중지 상품은 안 들어간다.

원래는 product 전부가 대상이었는데 조사할 때 범위를 좁힌 것이 그대로 남았다. 조사용 조건과 로직상 필요한 조건이 코드에서 구분이 안 되고 둘 다 그냥 where 다.

나중에 그 where 를 보는 사람은 그 조건에 이유가 있을 것으로 본다. 그래서 지우지 않고 그대로 두게 되고 시간이 지나면 그것이 정상 동작이 된다.

표시를 남기기로 했다

조사용으로 넣는 것에 표시를 붙였다.

// TEMP 2016-06-19 원인 조사용. 확인 후 제거
$rows = $this->db->where('status', 'normal')->get('product')->result();

TEMP 로 검색하면 나온다.

$ grep -rn "TEMP " --include=*.php application/

배포 전에 이것을 돌려서 남은 것이 있는지 본다.

검사에 넣었다

사람이 기억해서 grep 을 돌리는 것은 빠뜨리므로 배포 스크립트에 넣었다.

CNT=$(grep -rn "TEMP " --include=*.php application/ | wc -l)
if [ "$CNT" -gt 0 ]; then
  echo "임시 코드가 남아 있습니다 (${CNT}건)"
  grep -rn "TEMP " --include=*.php application/
  exit 1
fi

남아 있으면 exit 1 로 배포가 멈춘다. 처음에 돌렸더니 네 건이 나왔고 전부 몇 달 전에 넣은 것들이었다.

사람이 기억해서 지우는 것에 기대지 않고 구조가 막게 만드는 것이다.

검증 — 검사가 대상을 보고 있는가

검사를 넣고 나서 그것이 실제로 무엇을 보고 있는지도 확인했다. 통과했다는 결과만으로는 대상을 제대로 훑었는지 알 수 없다.

TOTAL=$(find application -name "*.php" | wc -l)
if [ "$TOTAL" -eq 0 ]; then
  echo "대상 파일이 없습니다. 경로 확인"
  exit 1
fi
echo "대상 ${TOTAL}개 파일 검사"

find 가 준 TOTAL 이 0이면 경로가 틀린 것이고 그것이 임시 코드 없음으로 읽히면 안 된다.

grep 은 이 둘을 종료 코드로 갈라 준다. 찾는 것이 없어서 0건이면 1이 오고 경로가 없어서 못 훑었으면 2가 온다.

화면에 찍히는 것은 양쪽 다 없어서 눈으로는 구분이 안 된다. 경고를 지우려고 표준 오류를 버려 두면 그 단서마저 사라진다. 실제로 경로를 잘못 줘서 아무것도 안 보고 있던 적이 있었다.

코드를 안 고치는 방법과 커밋 분리

애초에 코드를 안 고치면 남을 것도 없다. 세 가지를 봤다.

먼저 조회로 확인하는 것이다. 코드에서 where 를 넣는 대신 GROUP BY 로 직접 본다.

SELECT status, COUNT(*) FROM product GROUP BY status;

다음은 log_message 로 확인하는 것이다. 조건을 바꾸는 대신 값을 찍는다.

log_message('debug', "동기화 대상: " . count($rows) . "건, 상태별: " . json_encode(array_count_values(array_column($rows, 'status'))));

로그는 남아도 로직을 안 바꾸고 수준을 낮게 두면 운영에서 안 찍힌다. 마지막은 대상을 안 좁히고 결과를 거르는 것으로 조회는 그대로 두고 화면에 찍을 때만 거른다.

세 가지 중에 두 번째를 주로 썼는데 log_message 는 남겨도 부작용이 없다.

그래도 코드를 고쳐야 할 때가 있는데 그때는 원래 줄을 지우지 않고 남겼다.

// TEMP 2016-06-19 원인 조사. 아래 원본으로 되돌릴 것
// $rows = $this->db->get('product')->result();
$rows = $this->db->where('status', 'normal')->get('product')->result();

되돌릴 때 주석을 풀면 되고 원래가 무엇이었는지 기억 안 나서 못 되돌리는 일이 없다. 다만 이것도 오래 두면 안 되고 확인이 끝나면 바로 되돌린다.

조사용 변경과 실제 수정을 한 커밋에 넣으면 되돌리기 어렵다. 조사할 때는 svn commit 을 안 하고 원인을 찾으면 조사용을 되돌린 뒤 수정만 커밋했다.

$ svn status
M  application/models/product_model.php    ← 조사용? 수정?
M  application/controllers/sync.php

작업 사본에 조사용이 남은 채로 다른 것을 커밋하면 같이 들어가므로 커밋 전에 무엇이 바뀌어 있는지 봤다.

정리


Share this post on:

Previous Post
매출을 검증하는 화면을 만들며
Next Post
소켓 서버를 다른 플랫폼으로