ai-coding-mines목차GitHub

롱폴링은 소비자가 하나여야 한다 — 같은 토큰으로 두 프로세스를 띄우지 마라

Git · 자동화

증상

챗봇 명령이 가끔 안 먹는다. 에러는 안 난다. 같은 명령을 다시 치면 되기도 한다. 네트워크 탓으로 넘어가기 딱 좋다.

원인

같은 봇 토큰으로 두 개의 프로세스가 각자 롱폴링(getUpdates 계열)을 돌리고 있었다. 이런 API는 토큰 하나에 소비자 하나를 전제한다. 둘이 붙으면 서버는 대기 중인 쪽에 메시지를 넘기고 큐에서 지운다. 결과적으로 메시지를 둘이 나눠 가진다 — 한쪽이 받은 명령을 다른 쪽은 영영 못 본다.

★★ 증상이 에러가 아니라 누락이라 진단이 늦는다. 절반은 정상 동작하기 때문에 "동작은 한다"로 보인다. → 이 문서의 [조용한 실패] 계열.

해법

용도별로 토큰을 나눈다. 알림 봇과 명령 봇, 또는 명령 계열별로.

★ 처음에는 봇을 나눈 이유가 "알림이 한 채널에 섞여 급한 것이 잡음에 묻힌다"는 운영 편의였다. 명령 처리를 추가한 순간 그것이 동작 정합성의 필수 조건으로 바뀌었다. 편의로 해둔 분리가 나중에 필수가 되는 경우가 있다 — 반대로, 편의라고 판단해 합쳐뒀다면 여기서 터졌다.

검증 방법

★★ 두 프로세스를 동시에 띄운 상태에서 테스트하라. 하나만 돌 때는 이 함정이 절대 나타나지 않는다. 명령을 10회 보내 10회 다 처리되는지 센다. 개발 중에는 로컬 인스턴스와 서버 인스턴스가 같은 토큰을 쓰는 경우가 흔하니, 배포 후 로컬을 끄는 것까지 절차에 넣는다.

★ 0건 응답에는 사유를 붙여라

원격에서 화면 하나로 판단해야 하는 자동화라면, "조건 미달"만 출력하는 응답은 다음 행동을 못 정하게 만든다. 이미 처리된 건인지 진짜 미달인지 구분이 안 되기 때문이다. 0을 반환할 때야말로 왜 0인지를 같이 보내야 한다.