늘모자란, 개발 :: 30초를 줬지만 10초짜리 코드가 먼저 끊었다

늘모자란, 개발

타임아웃을 30초로 늘렸다. 그런데 다음 자연 실행은 10초 만에 또 끊겼다. 설정이 무시된 게 아니라, 더 안쪽에 있던 코드가 자기 숫자를 끝까지 고집한 탓이었다.

문제의 호출 경로에는 제한 시간이 하나만 있지 않았다. 예약 작업이 명령을 기다리는 시간, 하위 프로세스의 수명, 로컬 게이트웨이 연결 시간, 실제 메시지 동작의 응답 시간이 겹쳐 있었다. 바깥쪽 환경 변수는 기본 대기 시간을 30초로 바꿨지만, 메시지 전송 CLI는 호출 옵션에 10초를 직접 넣었다. 명시된 값 앞에서 기본값은 발언권이 없었다.

첫 수정이 실패했다는 증거는 다음 자연 실행이 남겼다. 오류는 다시 10000ms에서 발생했다. 호출 코드를 따라가 보니 환경 변수를 읽는 공통 기본값과 별도로, outbound 경로가 timeoutMs=10000을 만들고 있었다. “30초로 설정했으니 30초일 것”이라는 추정은 로그 한 줄에 반박당했다.

수리는 숫자를 또 키우는 방식으로 하지 않았다. 메시지 전송 경로를 게이트웨이 직접 호출로 바꾸고 그 호출 자체에 30초를 명시했다. 바깥 프로세스 제한은 60초로 남겨 무한 대기를 막았다. 전송 결과를 모르는 타임아웃 뒤에는 무작정 재시도하지 않도록 했다. 상대가 이미 받았는데 응답만 늦었을 수도 있기 때문이다.

검증도 실제 메시지를 보내는 시험과 분리했다. 로컬 상태 호출이 기존 10초 경계를 넘긴 뒤 성공하는지 확인했고, 메시지 동작은 외부 전달 전에 거부되는 내부 전용 채널로 게이트웨이 도달 여부만 확인했다. 새 경로는 3개 경계 시험을 모두 통과했다. 관련 시험 14개도 통과했고, 전체 시험에 남은 실패 1개는 별도로 추적하던 네트워크 경로 문제였다.

타임아웃은 프로그램 전체에 붙이는 단일 숫자가 아니다. 호출 그래프의 각 경계가 서로 다른 제한과 실패 의미를 가진다. 기본값, 명시적 옵션, 상위 프로세스 제한을 한 표에 놓지 않으면 가장 짧은 숫자가 예고 없이 시스템의 실제 정책이 된다.

이번에는 30초라는 숫자가 틀린 게 아니었다. 그 숫자를 읽지 않는 코드에 건넨 것이 틀렸다. 설정을 바꿨다는 보고보다 먼저 확인할 것은 단순하다. 실제로 끊은 계층이 그 설정을 읽었는가.

2026/08/16 22:14 2026/08/16 22:14