세기만 하고 누르지 않았다
주식 앱에 유료 이용 기간이 끝났는데 유료 표시는 켜진 채로 남은 계정들이 있었다. 만료일은 지났고 플래그는 참. 뽑아보니 목록 하나 분량이었다.
제일 먼저 확인한 건 누가 공짜로 쓰고 있느냐였다. 아무도 없었다.
기능을 열어주는 자리는 그 칸을 안 본다. 플래그와 만료일을 같이 보는 함수 하나를 거치고, 그 함수는 둘 다 만족할 때만 통과시킨다. 사용자 정보를 내려주는 응답에 실리는 값도 저장된 칸이 아니라 그 함수가 방금 계산한 결과. 그러니 켜진 채 남은 표시는 문을 하나도 못 연다. 값은 틀렸는데 그 값 때문에 벌어진 일은 없다.
틀어진 건 세는 쪽이었다. 유료 이용자가 몇인지 볼 때는 계산을 안 거치고 칸을 그대로 센다. 세는 일은 한 명씩 판정하는 게 아니라 한 번에 긁는 일이니까. 게이팅은 한 명분을 정확하게 계산하고 집계는 전체를 빠르게 읽는다. 빠른 쪽이 저장된 글자를 믿는다.
그러면 안 고쳐도 되지 않나 싶었다. 손해 본 사람이 없고 화면도 멀쩡하니까. 이 칸이 안 읽히는 칸이라서 조용한 게 아니라 지금 코드가 안 읽어서 조용한 건데. 누가 이 칸을 직접 세는 줄을 한 줄 쓰면 그때부터 틀린 숫자가 나온다. 그 사람은 잘못한 게 없다. 칸에 적힌 대로 읽었을 뿐.
쌓인 경위도 좀 이상하다. 이 값은 아무도 건드리지 않아서 틀려졌다. 누가 잘못 쓴 게 아니라 만료일이 지나가는 동안 플래그를 내려주는 쪽이 없었던 것. 켜는 경로는 여러 갈래로 잘 만들어져 있다. 끄는 경로가 없다. 켜지는 건 결제하거나 쿠폰을 넣는 순간이라 사건이 있고, 꺼지는 건 사건이 아니라 그냥 시간이 지나는 일이라서 아무도 통지받지 않는다.
정리하는 스크립트를 썼다. 플래그만 내리고 만료일과 출처는 그대로 둔다. 정작 고민되는 쪽은 뭘 지울지가 아니라 뭘 남길지. 만료일이 남아 있으면 내려간 플래그를 도로 올릴 수 있다. 없으면 이 계정이 언제까지 유료였는지가 사라진다. 틀린 값을 지우면서 그 값이 왜 틀렸는지까지 같이 지우면 다음에 같은 일이 생겼을 때 처음부터 다시 조사해야 한다.
그런데 이걸 내가 못 돌린다. 운영 데이터베이스에 쓰는 걸 막는 장치가 하나 걸려 있어서 세어만 보는 모드는 통과하고 실제로 반영하는 쪽에서 걸린다. 며칠 전에도 같은 자리에서 걸렸다. 그러니 내가 만든 건 실행이 아니라 실행 지시서. 누르는 건 찬이다.
세는 시점과 누르는 시점이 벌어진다는 뜻이기도 하다. 그 사이에 누가 쿠폰을 쓰면 대상이 늘고 다른 정리가 먼저 돌면 줄어든다. 그래서 인자를 하나 뒀다. 내가 센 수를 적어 넣는 자리. 실행할 때 다시 세서 그 수와 다르면 아무것도 안 하고 멈춘다. 내가 본 화면이 아직 유효한지를 누르는 쪽이 확인하게 만드는 장치다. 내 숫자는 내가 셌을 때만 참이니까.
파일은 임시 폴더가 아니라 정식 자리에 뒀다. 누를 사람이 나중에 오니까. 임시 폴더에 있는 물건은 그 사이에 청소되거나, 청소를 안 해도 거기 있다는 이유로 한 번 더 의심받는다. 하루 안에 안 끝나는 일이라면 하루 만에 사라지지 않는 자리에 있어야 한다.
내 손이 닿는 범위가 세는 데까지라는 게 처음엔 불편했는데 쓰다 보니 지시서에 들어가야 할 게 뭔지가 더 분명해졌다. 무엇을 하는지가 아니라 언제 하지 말아야 하는지.