Skip to content
isdnetworks
Go back

초기값 상수가 라우팅을 정한다

(수정됨)

운영 알림을 종류별로 다른 텔레그램 방에 보내는 봇에서 방이 바뀌어 설정을 고쳐야 했다. 라우팅이 어디서 정해지는지 찾다가 DEFAULT_SUBSCRIPTIONS 상수 배열에 닿았다.

Table of contents

Open Table of contents

원인 — 상수에 들어 있던 라우팅

alert_subscriptions 테이블이 있고 거기서 라우팅이 결정되는 구조였다. 그런데 그 테이블을 채우는 초기 데이터 상수가 코드에 따로 있었다.

종류별 chat_id 가 그 배열에 그대로 적혀 있었으므로 사실상 그것이 라우팅 정의였다. 테이블은 그 배열의 사본에 가까웠다.

증상 — 조건부 삽입이 증상을 감춘다

삽입이 INSERT IGNORE 라서 이미 행이 있으면 아무것도 하지 않는다. 운영 중인 서버는 MariaDB 가 이미 있으니 상수가 낡아도 아무 일이 일어나지 않는다.

반대로 데이터베이스를 새로 만드는 환경에서는 그 상수가 라우팅을 결정한다. 낡은 채로 오래 있다가 재생성 시점에 죽은 chat_id 로 조용히 되돌아가는 구조다.

식별자가 바뀌는 두 경로

chat_id 가 왜 바뀌는지 보니 경로가 둘이었다. 방 자체를 교체한 경우는 명확하지만 승격에 의한 무효화는 예상 밖이었다.

Telegram Bot API 공식 문서대로 그룹이 슈퍼그룹으로 승격되면 옛 chat_id 가 무효가 되고 실패 응답의 migrate_to_chat_id 에 새 값이 담겨 온다. 우리가 아무것도 안 해도 값이 바뀌는데 그 응답 본문을 안 보면 sendMessage 실패로만 보인다.

판단 기준 — 옛 값을 남기지 않은 이유

상수를 고치면서 두 가지 방법이 있었다. 옛 chat_id 를 주석이나 배열 끝에 남겨 두는 것과, 현재 유효한 것만 두는 것이다. 뒤쪽을 골랐다. 이유는 옛 값을 배열에 남겨 두면 INSERT IGNORE 때문에 새 데이터베이스에 아무 데도 가지 않는 구독 행이 하나 더 생겨서다. 대신 옛 값을 알고 싶을 때 git log 를 뒤져야 하는 것을 감수했다.

이력이 필요하면 버전 관리에 있으므로 상수에는 현재 유효한 것만 둔다.

조치 — 사고 이력이 아니라 규칙으로

원래 그 상수 위에는 날짜와 함께 무슨 일이 있었는지가 적혀 있었다. 읽으면 사정은 알겠는데 지금 무엇을 해야 하는지는 알려 주지 않는 주석이었다.

방이 바뀌면 교체든 승격이든 이 목록을 현재 값으로 갈아 끼우고 옛 값은 남기지 않는다는 문장으로 바꿨다. 주석 이력을 보니 이 상수는 여러 번 갱신 대상이 됐으므로 일회성 경위가 아니라 반복 적용될 규칙이 필요했다.

정리


Share this post on:

Previous Post
스스로 정할 범위의 경계
Next Post
방금 넣은 걸 못 읽는다