시간당 10번만 부를 수 있는데 18번 부르고 있었다
화면에 "수신 실패"가 계속 떴다. 서버가 죽은 것도, 키가 틀린 것도 아니었다. 그냥 내가 너무 많이 불렀다. 곱셈 한 번을 안 해서 생긴 일.
비트코인 탭에 지표 세 개를 붙였다. 어떤 무료 사이트에서 가져오는 값들이다.
붙인 날은 잘 됐다. 다음 날 켜보니 세 칸 모두 “수신 실패” 였다.
곱셈을 안 했다
원인은 허무했다. 그 사이트는 시간당 10번까지만 부를 수 있다. 그런데 내 프로그램은 비트코인 탭 전체를 10분마다 새로 불러오고, 그 안에서 지표를 세 개 가져온다.
60분 ÷ 10분 = 시간당 6번 갱신 6번 × 지표 3개 = 시간당 18번 호출
한도가 10인데 18을 불렀다.
더 나쁜 건, 초과분만 거절되는 게 아니라는 점이다. 한도를 넘긴 시점부터 그 시간이 끝날 때까지 전부 거절된다. 그래서 하루 종일 “수신 실패”였다. 붙인 날에 잘 됐던 건 그날은 몇 번 안 불렀기 때문이었다.
진짜 문제는 429가 아니었다
여기서 진짜 문제는 갱신 주기를 아무 생각 없이 정했다는 것이다.
10분은 비트코인 가격에 맞는 주기다. 가격은 계속 움직이니까. 그런데 나는 그 옆에 지표를 얹으면서 주기를 그대로 물려받았다. 이 지표들은 하루에 몇 번 바뀌지도 않는다. 10분마다 부를 이유가 애초에 없었다.
얼마나 자주 부를지는 데이터가 얼마나 자주 바뀌는지로 정해야 한다. 나는 옆에 있던 숫자를 그냥 따라 썼다.
그래서 지표만 따로 떼서 3시간으로 늘렸다. 3시간이면 시간당 한 번이 안 된다. 세 개를 다 불러도 한도의 3분의 1도 안 쓴다.
그런데 주기만 늘려서는 안 됐다
한 번 거절당하고 나면 그다음이 문제였다. 원래 프로그램은 이런 악순환에 빠져 있었다.
- 호출이 거절당한다 값을 못 받았으니 화면에 "수신 실패"를 띄운다
- 가진 값이 여전히 낡은 상태다 새 값을 못 받았으니 당연하다
- 낡았으니 다음 갱신 때 또 부른다 10분 뒤에 또, 그다음 10분 뒤에 또
- 한도에 걸린 상태에서 계속 두드린다 빠져나오려는 시도가 오히려 한도를 더 깊게 판다
그래서 세 가지를 더 넣었다.
첫째, 마지막에 성공한 값을 파일에 저장해두고 실패하면 그걸 계속 보여준다. 원래는 실패하면 값을 버리고 빈칸을 띄웠다. 어제 받아둔 멀쩡한 값이 있는데도 버린 것이다. 파일에 저장하니 프로그램을 껐다 켜도 어제 값을 들고 시작한다.
둘째, 실패하면 최소 20분은 다시 안 부른다. 성공하든 실패하든 마지막으로 시도한 시각을 따로 기억해 두고, 그때부터 20분은 쉰다. 위 그림의 악순환을 끊는 장치다.
셋째, 세 개 중 두 개만 받아왔을 때는 저장하지 않는다. 두 개만 받고 덮어쓰면 나머지 하나는 값을 잃는다. 게다가 “방금 갱신했다”고 기록되니까 3시간 동안 다시 안 부른다. 어제의 완전한 값이 오늘의 불완전한 값보다 낫다.
화면 문구도 고쳤다
원래는 값이 없으면 무조건 “수신 실패”라고 띄웠다. 이제는 대부분 어제 값이라도 들고 있으니, 정말 값이 없는 건 한 번도 받아본 적이 없을 때뿐이다. 그 경우만 “수신 대기 중”으로 바꿨다.
“수신 실패”는 뭔가 고장 났다는 뜻이고 “수신 대기 중”은 아직 안 왔다는 뜻이다. 화면을 보는 사람이 나 하나뿐이지만, 이 문구를 보고 “또 뭐가 터졌나” 하며 코드를 열어보는 시간이 아까웠다.
값이 몇 시간 전 것인지도 같이 적게 했다. 낡은 값을 보여줄 거면 얼마나 낡았는지도 같이 보여줘야 한다.
남은 교훈
- 한도를 먼저 계산해라. 갱신 주기 × 호출 개수. 곱셈 한 번이면 되는데 나는 안 했다.
- 갱신 주기는 데이터가 바뀌는 속도에 맞춰라. 옆에 있는 값을 그대로 물려받지 마라.
- 실패는 상태다. 실패했을 때 (a) 무엇을 보여줄지, (b) 언제 다시 시도할지를 둘 다 정해야 한다. 안 정하면 기본값은 “아무것도 안 보여주고 계속 두드리기”인데, 이게 최악이다.
- 일부만 성공한 걸 성공으로 치지 마라.
무료 서비스를 붙일 때는 안내 문서에서 호출 제한부터 찾아보는 게 습관이 됐다. 대부분 눈에 잘 안 띄는 곳에 한 줄로 적혀 있다.
이 글은 개인 프로젝트의 개발 기록입니다. 투자 자문이나 종목 추천이 아니며, 글에 등장하는 종목명은 프로그램의 동작을 설명하기 위한 예시입니다. 투자 판단과 그 결과에 대한 책임은 투자자 본인에게 있습니다.