제품··5분 읽기

매일 오는 제품의 가장 중요한 필드는 날짜다

서버는 매일 새 문제를 만들었는데 화면은 다음 날에도 어제 결과를 띄웠습니다. 진행 상태에 날짜가 없었고, 그런 죽음은 로그에 남지 않습니다.

#제품 원칙#리텐션#클라이언트 상태#DUGOUT 9

매일 여는 제품은 하루를 단위로 약속합니다. 오늘 오면 오늘 것이 있고, 내일 오면 내일 것이 있다는 약속입니다. 그 약속을 지키는 데 필요한 것은 생각보다 적습니다. 무엇이 어느 날의 것인지만 알면 됩니다. 너무 기본이라, 어딘가에서 누군가 이미 알고 있으려니 하고 넘기기 쉬운 것이기도 합니다.

KBO 팬을 위한 독립 프로젝트 DUGOUT 9에는 매일 새로 만들어지는 퀴즈 세 개, 오늘의 3게임이 있습니다. 서버는 그 약속을 지키고 있었습니다. 그런데 화면은 첫날 이후로 그 약속을 한 번도 지키지 않고 있었고, 저는 그것을 한참 뒤에야 알았습니다.

서버는 멀쩡했다

3게임을 다 풀면 결과 화면이 뜹니다. 오늘의 점수와 시즌 누적, 연속 기록이 나오는 화면입니다. 문제는 그 진행 상태에 날짜가 없었다는 것입니다. 상태는 "다 풀었다"만 기억했지, "언제 다 풀었다"는 기억하지 않았습니다.

그래서 다음 날 다시 들어와도 어제의 결과 화면이 그대로 떴습니다. 게임으로 직접 들어가도 "이미 완료"라는 카드가 떴습니다. 서버 쪽은 아무 문제가 없었습니다. 문제는 매일 새로 만들어지고 있었고, 점수도 날짜별로 받을 준비가 되어 있었습니다. 다만 화면이 요청을 보내지 않았을 뿐입니다. 매일 오라고 만든 제품이, 하루 쓰고 끝나는 앱이 되어 있었습니다.

그리고 아무도 몰랐습니다. 저도 몰랐습니다. 오류가 하나도 없었기 때문입니다.

팬의 입장에서 보면, 둘째 날 다시 왔을 때 보이는 것은 바뀌지 않은 게임이었습니다. 버그라고 신고할 거리도 없고, 다시 올 이유만 사라집니다. 이렇게 망가지는 매일 제품은 멈추지 않습니다. 그저 매일이 아니게 될 뿐이고, 그 피해를 입은 사람은 알려 주지 않습니다. 그냥 더는 열지 않습니다.

보내지 않은 요청은 어디에도 남지 않는다

이 결함이 오래 숨어 있었던 이유를 생각해 보면, 제가 제품을 확인하던 방식이 서버 중심이었기 때문입니다. 문제가 매일 만들어지는지, 채점이 맞는지, 점수가 제대로 쌓이는지. 그 질문들에는 전부 "그렇다"가 나왔고, 실제로 그랬습니다.

하지만 클라이언트가 요청을 보내지 않는 것은 로그에도 대시보드에도 남지 않습니다. 실패한 요청은 기록이 되지만, 보내지 않은 요청은 아무것도 아닙니다. 서버가 옳게 동작하는지만 보면, 이런 종류의 죽음은 원리적으로 보이지 않습니다. 개발하는 동안에는 상태를 수시로 지우고 다시 시작하니, 둘째 날이라는 상황 자체를 겪을 일도 거의 없었습니다.

날짜를 붙이고, 하루치만 비운다

고친 방법은 단순합니다. 진행 상태에 날짜를 붙이고, 날짜가 바뀌면 하루치만 비웁니다. 시즌 누적은 그대로 남깁니다. 오늘 푼 것과 지금까지 쌓은 것은 수명이 다르기 때문입니다. 자정에 전부 비우는 쪽이 코드로는 더 쉬웠습니다. 하지만 그건 버그 하나를 다른 버그로 바꾸는 일이었습니다. 매일 오는 팬일수록 시즌 기록이 매일 처음으로 돌아가는 것을 보게 됐을 테니까요.

여기에 한 가지가 더 필요했습니다. 앱처럼 설치해 두고 쓰면 화면이 며칠씩 열린 채로 있기도 합니다. 그러면 처음 열 때 날짜를 한 번 확인하는 것으로는 부족합니다. 그래서 화면이 켜져 있는 동안에도 자정이 지났는지를 확인합니다.

날짜를 붙이고 나니 연속 기록도 같이 정직해졌습니다. 예전에는 하루를 건너뛰고 와도 이어진 것처럼 +1이 됐습니다. 연속 기록이 날짜를 몰랐으니 당연한 일이었습니다. 이제는 하루를 건너뛰면 끊깁니다. 숫자는 조금 덜 친절해졌지만, 연속 기록이라는 이름에 맞는 숫자가 됐습니다.

둘째 날을 직접 열어 본다

이 일에서 남은 습관은 하나입니다. 매일 오는 제품이라면, "2일차에 무엇이 보이나"를 직접 열어 보는 검사를 따로 둡니다.

  • 오늘을 끝낸 상태에서 날짜만 하루 넘겨 다시 연다.
  • 화면을 열어 둔 채로 자정을 넘긴다.
  • 하루를 건너뛰고 연다.

세 경우 모두 서버 테스트로는 잡히지 않습니다. 서버는 그 상황에서도 옳게 동작하기 때문입니다. 확인해야 하는 것은 화면이 오늘을 오늘로 알아보는가입니다. 너무 당연해서 적어 둘 생각을 못 하는 종류의 검사이고, 바로 그래서 한 번도 해 보지 않았던 검사였습니다.

매일 오는 제품을 만들면서 저는 매일 새로 만들어지는 것, 그러니까 문제의 품질과 점수의 정확성에 주의를 거의 다 썼습니다. 정작 그 모든 것을 매일로 만들어 주는 것은 날짜 필드 하나였습니다. 그 필드가 빠지면 나머지가 아무리 잘 돌아도 제품은 첫날에 멈춥니다. 매일 오는 제품의 가장 중요한 필드는 날짜라고, 이제는 처음부터 적어 두려고 합니다.