상장 프로젝트들의 텔레그램 채널에서 수집한 공지에서 코인 심볼을 뽑아야 해서 몇 편을 열어 보니 본문에 (DPL) 처럼 괄호로 들어 있었다. 본문에서 Pattern.compile("\\(([A-Z]{2,6})\\)") 로 뽑으면 된다고 정리하고 구현으로 넘어가려던 참에 실측 없이 넘어간다는 지적을 받았다.
Table of contents
Open Table of contents
배경 — 몇 개를 보고 세운 일반화
내가 확인한 것은 몇 편뿐이었고 그것이 전 채널을 대표한다는 근거는 어디에도 없었다. 그런데 정리한 문장은 본문에 있다는 단정이었다.
미확인으로 남겨 둔 항목이 셋 있었고 그것들이 설계에 영향을 줄 수 있는 자리였다. 그래서 구현으로 넘어가지 않고 셋을 전부 확인하기로 했다.
검증 — 반례가 두 채널에서 나왔다
채널별로 본문에 심볼이 있는지 전부 확인하니 셋에는 있고 둘에는 아예 없었다. 있는 셋도 형태가 달라서 하나는 본문 괄호이고 하나는 링크 파라미터였다. Telegram Bot API 공식 문서대로 text_link 엔티티는 눈에 보이는 글자 밖 url 필드에 주소를 들고 있어서, ?symbol=MOPL 은 message.text 에는 없고 entities 에만 있었다.
본문에서 뽑으면 된다는 문장은 다섯 중 셋에서만 참이었고 나머지 둘은 그 방식으로는 아무것도 못 뽑는다. 표본 몇 개로 세운 일반화가 전수 확인에서 그대로 깨졌다.
조치 — 2단 구성과 금지한 경로
두 가지 방법이 있었다. 채널마다 추출기를 따로 짜는 것과, 본문 추출을 1순위로 두고 실패하면 프로젝트명 완전일치로 coin_master 사전을 조회하는 2단 구성이다. 뒤쪽을 골랐다. 이유는 채널이 다섯에서 늘 때마다 추출기를 더 짜는 일을 감당할 사람이 없어서다. 대신 프로젝트명이 사전과 한 글자라도 다르면 못 뽑는 것을 감수했다. 완전일치가 0건이거나 여럿이면 추측하지 않고 건너뛰면서 ActiveMQ 의 알림 큐로 알리게 했다.
검색으로 심볼을 찾아 채우는 방법은 금지로 못박았는데 전에 본문의 금액 숫자를 심볼로 오인한 사고가 있었기 때문이다. 안 보내는 것과 틀린 것을 보내는 것 중에서 뒤쪽이 훨씬 나쁘다는 판단을 문서에 함께 적었다.
화면 판정 대신 직접 반환
두 번째 미확인은 관리자 화면의 메뉴 표시 상태로 권한을 판정하던 코드였고 그 방식 때문에 장애가 난 적이 있었다. 확인해 보니 항목별 권한을 직접 돌려주는 GET /api/me/permissions 가 이미 있었다.
그것으로 바꾸니 렌더링 타이밍에 의존하던 구조가 없어졌고 화면 판정은 폴백으로만 남았다. 증상을 막은 것이 아니라 그 증상이 나올 자리가 사라진 것이었다.
표본 수를 함께 적는 결론
세 번째는 공지의 이미지를 입력에 넣을지였는데 받아 보니 전부 로고와 광고 포스터 같은 장식이었다. 도표도 수치도 없어서 입력에서 제외했고 결국 셋 다 확인 전 계획과 결론이 달라졌다.
그대로 구현했으면 셋 다 만들고 나서 발견했을 것이고 되돌리는 비용이 훨씬 컸을 자리다. 이후로 결론에 표본 수를 함께 적어서 있다가 아니라 다섯 중 셋에 있다로 쓰게 됐다.
정리
- 몇 개를 보고 일반화하지 않고 전 대상을 훑는다
- 표본이 몇 개인지가 결론의 강도를 정한다
text_link처럼 보이는 글자 밖에 있는 값은 본문 정규식으로 못 뽑는다- 반례가 나오면
coin_master폴백을 두는 2단 구성으로 바꾼다 - 애매하면 건너뛰고 알리며 추측으로 채우지 않는다
- 사고 경로가 있으면 그 방법을 금지로 못박는다
- 화면 상태 판정보다
GET /api/me/permissions처럼 직접 반환하는 경로가 있으면 원인이 사라진다 - 입력에 넣을 것은 실제로 받아 보고 정한다
- 미확인 항목이 설계를 바꾸므로 구현 전에 닫는다