상품 이미지를 읽는 방식을 바꿔야 했다. 지금은 자식이 부모 이미지를 그대로 참조하는데 앞으로는 자식이 자기 이미지를 갖고 없을 때만 부모 것을 쓰게 하려는 것이었다.
Table of contents
Open Table of contents
같이 내보낼 때의 문제
읽는 곳을 세니 여덟 군데였고 상세와 목록과 내보내기와 마켓 전송과 캐시 생성과 관리자 화면과 배치가 걸려 있었다. 쓰기 쪽도 자식 저장 시 자기 이미지를 만들도록 바꿔야 했다.
처음 계획은 둘을 같은 배포에 넣는 것이었는데 문제가 있었다. 읽기 여덟 곳 중 하나가 잘못되면 화면이 깨지고 쓰기가 잘못되면 자식 이미지가 안 생기는데 둘이 같이 나가면 문제가 생겼을 때 어느 쪽인지 알 수 없고 되돌리려 해도 통째로 되돌려야 한다.
발동할 수 없는 조건
순서를 바꿔 읽기를 먼저 내보내되 그 코드가 절대 발동하지 않는 조건으로 넣었다. 읽기 로직을 헬퍼 하나로 모으고 자기 것이 있으면 자기 것을 없으면 부모 것을 반환하게 했다.
지금은 자식에게 자기 이미지가 하나도 없으므로 첫 분기가 항상 거짓이고 모든 호출이 부모 것을 반환한다. 여덟 곳을 건드린 배포인데 동작이 하나도 안 바뀌는 상태가 된다.
무동작의 증명
안 바뀔 것 같다는 판단으로는 부족해서 배포 전에 셋을 확인했다. 자식에게 자기 이미지가 0건인지를 실제로 셌는데 하나라도 있으면 그 상품만 동작이 바뀐다.
여덟 곳이 정말 다 교체됐는지도 검색으로 셌다. 기존 호출이 남아 있으면 그곳만 옛 경로를 타서 나중에 화면마다 다른 이미지가 나온다. 마지막으로 배포 전후에 상품 20건의 이미지 주소를 뽑아 대조했고 전부 같았다.
플래그 하나로 한 전환
읽기가 나간 뒤 쓰기를 별도로 배포하면서 기능 플래그를 달았고 기본값은 꺼짐이었다. 배포해도 아무 일이 없다.
그다음 카나리 서버 한 대에서만 켰다. 그 순간부터 그 서버로 저장된 상품만 자기 이미지를 갖게 되고 그 상품에서만 읽기 쪽 첫 분기가 발동하므로 여덟 곳을 건드린 변경의 실질 위험이 카나리 한 대에 갇혔다.
관측과 적용 조건
카나리에서 이틀 동안 셋을 봤다. 자식 이미지가 생성되는지를 건수로 세고 그 상품의 화면을 표본으로 확인하며 마켓 전송을 로그와 상대 화면으로 확인했다.
셋 다 정상인 것을 보고 나머지 서버에 켜고 기존 상품에 대한 소급 생성 배치를 돌렸다. 이 방식은 준비 비용이 있으므로 읽는 곳이 많고 읽기와 쓰기를 분리할 수 있으며 되돌리기가 비싼 경우에 쓴다. 새 경로가 기존 데이터에서도 발동하면 이 방법이 성립하지 않고 그때는 읽기 쪽에도 플래그가 필요해 분기가 두 겹이 된다.
정리
- 읽기 변경과 쓰기 변경을 같이 내보내면 어느 쪽 문제인지 모른다
- 읽기를 먼저 내보내되 현재 데이터에서 참이 될 수 없는 조건으로 만든다
- 안 바뀔 것 같다가 아니라 증명한다
- 대상 0건과 호출부 전수 교체와 표본 전후 비교를 확인한다
- 전환은 쓰기 쪽 플래그 하나로 한다
- 위험이 그 서버와 그 시점 이후 데이터로 좁혀진다
- 카나리에서 생성과 화면과 외부 전송 셋을 확인하고 넓힌다
- 새 경로가 기존 데이터에서도 발동하면 이 방법은 성립하지 않는다