2022.10 ~ 2022.12
## 회고
그렙에 입사하기 전 가장 궁금했던 것 중 하나는 프로그래머스에서 코드 실행과 채점을 구현한 방법이었다. 그런데 막상 입사하고 보니, 코드실행기의 기본 기능을 완성한 후에는 실행하는 언어의 버전 업데이트만 진행하고 거의 유지보수를 하지 않는 상태였다. 그래서 Node.js로 작성된 코드실행기 코드에서 콜백지옥 코드와 한참 전에 아카이브된 라이브러리를 사용하는 것을 보고 상당한 놀란 기억이 있다.
입사 후 2년이 지나도록 코드실행기는 건드려보지도 못하다가 어느 날 언어 버전 업데이트 태스크가 나한테 할당되었다. 팀원 중 코드실행기 언어 버전 업데이트를 해본 사람이 한 명 밖에 없어서 버스 팩터를 높이려는 목적이 컸다. 팀장님과 의논해서 버전 업데이트 요청이 가장 많았던 js를 먼저 업데이트하고 다른 언어들은 이후에 업데이트하기로 했다.
코드실행기 언어 버전 업데이트 자체는 간단했는데 이후 과정이 번거로웠다. 언어 버전을 업데이트하면 같은 코드여도 실행 시간이 달라질 수 있기 때문에 프로그래머스에 있는 모든 테스트케이스에 대한 실행 시간을 재계산해서 저장하는 과정을 업데이트할 때마다 반복해야 했다. 문제는 시험이 진행 중일 때 갑자기 언어의 버전이 변경되면 형평성에 어긋날 수 있어서 아무도 시험을 보지 않는 시간에 업데이트하고 실행 시간을 재계산해야했다.
만반의 준비를 갖추고 js 업데이트를 밤 10시에 진행하려고 했는데 시험에 응시 중인 사람이 있어서 12시 30분까지 미뤄졌다. 그런데 스테이징 서버에서만 테스트해보다가 프로덕션에서 배포하니까 aws 권한 문제로 배포에 실패했다. 한참 찾아서 문제 있는 부분을 수정하고 다시 배포를 진행해서 성공했는데 업데이트한 버전이 적용되지 않았다. 작업을 진행한 pull request를 master에 병합하지 않은 상태로 master를 배포한 것이었다. 이마 한 대 쳐서 정신 차린 후에 pull request 병합하고 제대로 배포를 끝냈다. 그리고 실행 시간 재계산까지 마치고나니 4시가 넘었었다.
그렇게 다음 업무는 자연스럽게 코드실행기 배포 방식 개선으로 정해졌다. 언어 버전 업데이트를 하기 전의 나였다면 가끔 배포하는 코드실행기에 리소스를 들이는 것에 반대했겠지만, 언어 버전 업데이트를 경험해보니 반대를 할 수가 없었다. 지금 생각해보면 처음부터 코드실행기 배포를 개선시키려는 팀장님의 큰그림이었던 것 같기도 하다.
코드실행기 배포 개선의 첫 번째 단계는 실행 시간 재계산을 별도로 진행할 수 있도록 하는 것이었다. 이를 위해 코드실행기 인프라를 하나 더 구축하고 로드밸런서를 분리해서 사용자에게 영향을 주지 않고 재계산을 할 수 있도록 만들었다. 프로덕션 코드실행기에 언어 버전 업데이트를 하기 전에 재계산용 코드실행기에 먼저 업데이트를 진행해서 실행시간을 재계산하고 기록하면 된다. 이 작업을 끝내서 다음에 버전 업데이트를 할 때는 새벽 2시에는 잠을 청할 수 있게 되었다.
실행시간 재계산을 미리 진행해서 상당한 수면시간을 확보했지만 아직 더 많이 확보할 여지가 남아있었다. 이 때는 코드실행기의 언어 버전을 업데이트한 후 곧바로 웹서버에도 언어 버전을 반영해서 배포해야 했는데, 코드실행기 버전도 미리 업데이트하고 웹서버에 버전 반영만 밤에 진행하는 방식으로 변경하기로 했다. 기존에는 코드실행기가 정해진 언어 버전 하나만 실행할 수 있었는데 여러 버전 중 선택해서 실행할 수 있도록 구조를 수정해서 이를 달성했다. 이로써 낮에 실행시간 재계산과 코드실행기 언어 버전 업데이트를 미리 진행하고 밤에는 웹서버에만 언어 버전을 수정해서 배포하면 끝나는 형태가 되었다.
관리하지 않는 중요한 프로젝트를 건드리는 것은 상당히 힘든 일이었다. 일단 구조를 이해하는데도 시간이 오래걸렸고 작은 것 하나 수정하려고 해도 어떤 영향이 있을지 몰라서 조심스러웠다. 코드를 둘러볼 때 변수가 어떤 역할을 하는지 알기가 너무 어려워서 ts를 도입하고 싶은 욕구가 강하게 오기도 했다. 그래도 나에게 주어진 시간을 고려해서 복잡한 부분에만 jsdoc을 추가하는 것으로 만족해야 했다. 그래도 나름 녹슨 레거시에 기름칠하는 노하우를 깨달은 것 같기도 하다.