Search

[해커톤 후기] 42 Piscine Golang

Created
2021/11/08
Tags
42seoul
42서울
해커톤
Golang
Piscine Golang

1. 해커톤 공지 및 사전 준비

2021년 10월 14일에 평온한 저녁 보내고 있을 때, 슬랙을 뜨겁게 달구는 공지가 하나 올라왔다. 42서울에서 진행하는 해커톤이었고, 주제는 Piscine 제작이었다.
다른 분들께 얘기를 들어보니 2020년에도 해커톤이 있었다는 것을 알 수 있었는데, 지원 규모가 조금 더 커졌다는 것을 알 수 있었다. 참가 의사에 대해서는 모호했지만, 만일 해커톤 참여를 한다면 어떤 것으로 할 수 있을까 하고 고민을 했었다. 문득 C, C++ 외에 내가 Golang에 관심이 있었다는 것이 생각나서, Golang이 있다면 참가해야지 하고 있었다.
iOS, Flutter, Java, Python, 자취 요리, 창업 등의 다양한 주제로 Piscine을 제작하려는 아이디어가 보였지만, Golang을 주제로 한 Pisicne은 안 보여서 아래처럼 Golang만 안 보인다는 글을 올렸다.
그렇게 얼마 시간이 지나고 나서 Golang을 주제로 하는 팀이 나왔고, 정말 웃기게도 태그를 보면 이미 팀 구성이 되어 있는데도 팀 구성이 안 된 줄 알고 min-jo님께 DM을 드렸었다. 당연히 이미 구성된 팀이었기에 참가가 안 되었는데, 운이 좋은건지 나쁜건지 kalee님께서 회사 일정 때문에 참가가 힘들다고 하셔서 대타로 해커톤에 참여할 수 있었다.
해커톤 시작은 10월 25일부터였기 때문에 10일 정도의 시간이 있었고, 팀 픽스를 위해 팀 정보들 기입을 할 수 있도록 10월 15일에 다같이 모여서 회의를 했다. 해커톤 참가 신청서에서는 Piscine 주제 및 취지 등을 간단하게 물었고 특히 팀 이름을 기재하도록 요구했는데, 내가 준비해온 Go ? Ahead !라는 팀 이름에 좋은 반응을 얻어서 이대로 정해졌다.
이어서 해커톤 시작 전까지 준비해올 것들에 대해서 얘기를 나눴다. 나는 대체 멤버로 왔기 때문에 어떤 식으로 논의가 진행되고 있는지 몰랐는데, kalee님께서 주제 별로 나눠놓은 일정을 기반으로 빌드업을 계획하고 있었던 것을 알 수 있었다. 주제가 잘 나눠져 있다고 생각했기 때문에 10월 24일에 미리 회의를 한 번 하기로 하고, 그 전까지는 Golang을 각자 공부해오는 것으로 회의를 마무리 했다.
우선 회의를 마치자마자 Golang 관련 책을 알아보기로 했다. 유튜버 Tucker가 생각나서 Tucker의 Go 언어 프로그래밍 이라는 책을 찾아보고, 여타 다른 책들을 알아보다가 결국에는 이 책을 구입했다. 2021년 3월 쯤 Golang에 대해서 기본 문법을 배웠던 덕에 책을 읽는 속도는 꽤 났다. 특히 Struct, Method, Interface, Duck Typing, SOLID, Type Assertion, Type Switch에 대해서 배울 때는 왜 3월에 Golang 문법 익힐 땐 이런게 잘 안 읽혔지? 하면서 정말 재밌게 시간을 보냈다. 결국 3일 뒤 책을 완독할 수 있었고, 트렐로에 제시된 카워드들을 살펴보러 갔다.
트렐로에 제시된 키워드들 중 모르는 것 위주로 공부를 시작했고, 특히 Golang에서의 패키지 관리의 지식은 전무했기 때문에 이를 중심으로 자료를 찾아봤다. 또한 그 과정에서 Effective Go, Learn Go with Tests, Awesome Go 등에 대해서 찾게 되면서 (트렐로에 있었는데 이건 왜 못보고 넘어갔는지 ㅎㅎ... 결국에 읽긴 했다...), 이를 중심으로 내가 알고 있던 것들을 리뷰하고 새로운 지식들을 쌓았다.

2. 해커톤 사전 회의

사전 준비 기간 동안 열심히 공부를 하고 10월 24일이 되었을 때, 팀원들 간 해커톤 기간을 어떻게 보낼지 얘기를 나눴다. 우선 문제를 구성하더라도 양식도 그럴싸하게 하고 싶었던 욕심 때문에, 문서화 작업을 자처했다. 이에 따라 서브젝트 양식을 만들고, Notion에 협업 공간을 만들었다. 멘토님이 말씀하신 대로 해커톤 기간을 싸이클 별로 나누어 어떤 작업을 할지 간단히 Gantt Chart를 구성하여 명시해보았다.
싸이클 자체는 3일 기준으로 잡아서 다음과 같이 진행하기로 했다.
그리고 트렐로 주제들을 기반으로 문제 구성에 대한 회의를 진행했고, 각자 어떻게 문제를 맡을지 얘기를 나눴다. 대략적으로 아래 그림처럼 주제별 문제를 구상하게 되었고, 문제 구성은 각자가 챕터를 담담하는 방식보다는 한 챕터를 각자 나눠서 담당하자는 쪽으로 결정이 되었다.

3. 해커톤 시작

해커톤 시작 때 내가 맡은 업무는 문서 작성 및 백엔드 설정이었다. 단순히 문제를 만드는 것만으로는 아쉬워서 이왕 Golang을 주제로 Piscine을 만든다고 했을 때, 채점 서버가 있으면 어떻겠냐는 의견이 나왔었다. 이는 Golang은 테스트 코드 작성이 언어 단에서 권장되므로, 작성이 매우 용이하기 때문에 이를 채점 서버로 살리기 쉽지 않겠냐는 것에서 비롯되었다. 회의 결과로 시간이 남으면 채점 서버를 구성하는 것으로 결정을 했지만, 이왕 하는 거 최대한 하는 쪽으로 생각하자는 의미에서 초기 설정은 해두는 것으로 의견을 종합했다.
특정 URL로 GitHub 레포지토리를 들고 왔을 때, 이를 Clone하여 우리가 작성한 테스트 코드를 돌리는 식으로 구현할 계획이었고, 이에 따라 테스트 코드 연동만 제외하고 HTTP 핸들러를 빠르게 구성한 후에 로컬 상에서 HTTP 동작을 확인해두었다. 테스트 코드는 Piscine에서 이용할 문제를 정하고 코드가 구현되면, 이를 이용하기로 했다.
그리고 나선 백엔드 설정 외에 문서화 작업을 진행했다. 42내에서 이용되는 서브젝트를 살펴보면 문제 이전에 제시되는 꽤나 흥미로운 읽을거리가 존재하는데, 우리도 이를 넣자는 얘기가 나왔고 모두 흔쾌히 동의했다. 이에 따라 러쉬를 포함하여 8개의 각 서브젝트 별로 넣을 수 있는 내용들을 찾아서 넣는 것을 내가 담당하기로 했고, 나머지 팀원들은 문제를 구성하고 있는 것으로 결정했다.
여기서 문제가 발생했다. 아무래도 각자 챕터를 나눠서 진행하니 문제 구상이 꽤나 어렵다는 의견이 있었고, 문제가 만들어지더라도 흐름이 자연스럽지 않아서 피교육자에게 혼동을 줄 가능성이 높아보였다는 점이었다. 특히 10월 25일 밤에 진행된 멘토링에도 동일한 지적을 받을 수 있었다.

4. 해커톤 진행

1) 문제 담당 방식 변경

이전에 제시된 문제점으로 우리 팀은 팀원 별로 챕터를 담당하는 쪽으로 제작 방식을 바꿨다. 특히 사전 회의에서의 Day02, Day03, Day05가 흐름이 괜찮았기 때문에 나머지 챕터보다는 이들을 우선적으로 담당하는 것으로 정했다. Day02는 yongckim님, Day03은 min-jo님, Day05는 내가 맡기로 했다. 그리고 gRPC까지 다루면서 Day06을 마지막 챕터로 예상했던 것에서, Day06을 버리고 Day05에서 HTTP를 이용해보는 것을 마지막으로 두기로 했다.

2) 문제 제작 및 문서화

문제 담당 방식을 변경한 뒤에 팀원들은 꽤나 진행 방식에 만족하는 것으로 보았다. 팀원들이 문제를 만들면, 문제에 대한 스토리 라인 및 제출 파일 제한 등의 문제 요구 조건은 내가 빌드업 했다. 사전 회의에서 정한 내용이 꽤나 괜찮아서 그런지 스토리는 정말 스무스하게 적어낼 수 있었다.
그리고 문서화 중간 중간에 내게 할당된 문제도 만들었다. HTTP를 학습시키기 위해서 REST라는 개념을 넣고 싶었고, 이에 따라 API라는 개념을 넣어야 했다. 처음부터 큰 프로젝트 하나를 만들도록 만들면 러닝 커브에 따라 다들 배움의 즐거움보다는 의무감만 늘어날 것 같아서, 쉬운 문제부터 시작하여 빌드업 하는 방식으로 문제를 만들었다.
CRUD를 적용할 수 있는 사례부터 찾아보았고, 우리가 논의한 내용에서는 Map을 다루는 챕터는 없었기 때문에 이를 엮어내려고 했다. 결과적으로 사전이라는 주제가 생각이 났고, 사전을 Map으로 만들어 단순히 사전의 기능을 CRUD로 만들어내는 것으로 시작했다.
그리고 빌드업 할 때는 사전에 대한 커스텀 에러를 만들어 내면서 CRUD 기능을 발전시키도록 문제를 만들었고, 세 번째 문제가 되어서야 HTTP를 소개하면서 핸들러를 만들도록 명시했다. 핸들러를 만들 때 호출되는 기능은 기존에 구현한 CRUD를 호출하도록 유도했고, 그 다음 문제에서는 Logger를 달아서 기능들의 호출을 기록하도록 구성했다.
일련의 스토리를 문제들에게 부여하여 자연스럽게 이어지도록 다듬었고, 그렇게 내 파트는 끝났다. 문제를 구성하고 보니 평가지가 필요하다는 것을 깨닫고, 팀원들이 문제를 만드는 사이 평가지를 제작했다. 이를 템플릿으로 만들어서 팀원들도 문제 제작 후에 평가지를 쉽게 만들 수 있도록 만들었다.
나는 팀원들이 기존 문제를 구성하는 동안 Day00을 진행했. 여기서는 멘토링 때 들은 내용을 토대로 사용자들이 조금 더 쉽게 Golang을 접근할 수 있도록, 그리고 Piscine을 진행하는 동안 요구하는 내용들을 조금은 친절하게 안내해줄 수 있도록, 일종의 가이드 라인 목적의 문제를 제작했다. 그렇게 정해진 키워드들은 기본 문법, 내장 패키지, 패키지 관리였다.
10월 말에 Day00 문제 제작이 끝날 때쯤 팀원들 역시 맡은 부분의 문제 구성이 완료 되었고, Day01, Day04, Rush00만 남은 상황이 되었다. 나머지 작업에 대한 역할 분담을 논의했고, 그 결과로 yongckim님이 Day01과 Day04를 맡아주시기로 했고, min-jo님께서 Rush00을 맡아주시기로 했다.
3개의 챕터가 완성되었을 때 진행된 회의의 결과는 채점 서버 구현 및 배포에 욕심을 가져보자는 것이었다. 그리고 내가 백엔드 구현 및 인프라 구성을 맡아보기로 했다.

3) 백엔드 연동 및 인프라 구성

ft_server 외에는 직접적으로 인프라를 구성해본 경험이 없어서 많이 걱정되었다. 다행스럽게도 kalee님께서 많은 부분을 도와주셨다. 쿠버네티스 구성 요소에 대한 간단한 지식만 습득하고, kalee님을 찾아가서 쿠버네티스를 배우게 되었다. 이를 토대로 배포할 채점 서버의 yaml 파일을 작성하게 되었다.
참고로 쿠버네티스 도입은 팀원들의 학습 욕심 때문이었고 쿠버네티스 엔진으로 GKE를 이용했는데, 이는 무료 이용을 보장 받을 수 있는 환경이 구글 밖에 없어서였다. 또한 GKE를 웹 상에서 이용하는 것이 꽤나 불편해서 gcloud를 이용한 로컬 상에서의 제어로 넘어왔고, yaml 파일 작성 삽질 덕에 클러스터를 만들었다 지웠다하는 과정에서 꽤나 많은 과금이 나오면서 (무료 범위 내에서) minikube를 이용하는 쪽으로 방향을 바꿔갔다.
10월 31일부터 시작된 인프라와의 전쟁은 11월 1일에 마무리 지어서, 기존에 간단하게 만들어둔 백엔드를 퍼블릭으로 띄우는데 성공했다. 구조는 MariaDB - Backend - LoadBalancer 형태로 볼 수 있고, 이에 대한 접근은 CLI 프론트를 따로 만들어서 제공할 계획이었다.

4) 인프라 구조 변경

채점 서비스를 사용자에게 어떻게 제공할 것인가의 논의를 kalee님과 myoon님께 내 생각을 전달했다. 여러 논의 덕에 CLI 프론트를 제공하자는 초기 의견에서 Discord 봇 도입에 대해서 고려하는 선택지가 생겼다. Discord는 슬랙만큼 접근성이 높다는 장점과 다양한 상호작용을 단순히 Reaction으로 만들어낼 수 있는 장점이 있었기 때문이다. 특히 kalee님과 min-jo님이 Discord 봇 개발 경험이 있었기 때문에 이 의견에 힘이 쏠렸다. myoon님께서도 이 의견에 힘을 실어주셨고, 쿠버네티스로 배포한 인프라 구조 변경에서 도움을 많이 주셨다. 따라서 최종적으로 나온 인프라 구조는 다음과 같았다.
내가 인프라 구조도를 만들면서 yaml 파일을 수정하는 동안 kalee님께서 기존 백엔드 코드를 Discord 봇의 코드로 변경해주셨다. 이 과정에서 기존에 이용하고 있던 MariaDB는 kalee님의 설득으로 MongoDB로 변경되었다. 그리고 min-jo님의 Rush00도 마무리가 되었고, yonckim님의 Day01, Day04도 마무리가 되었다.

5. 해커톤 마무리

1) 작업 다듬기 및 발표 준비

각자 맡은 챕터가 준비 되었고, 크로스 체크가 마무리 되었다. 이는 평가지도 동일하게 검수되었다. 이 때가 이미 11월 3일이었고, 해커톤 발표가 2일 남은 시점이었다. 마지막 날을 고려하면 하루가 남은 시점이었기 때문에, 정말 밤을 새야하는 상황이었다. 11월 4일에 클러스터로 나갔을 때는 스태프 중에 코로나 확진자가 나오는 바람에 바로 귀가 조치되었고, 이와 같은 상황으로 해커톤 마무리는 11월 8일로 밀리면서 온라인 발표로 전환되었다.
우리 팀으로썬 좋은 기회였다. 마무리 상황에서 min-jo님께서 테스트 로직을 담당, kalee님이 Discord 봇 상호작용 로직을 담당, yongckim님께서 인프라 컨트롤링을 담당하면서 역할이 자연스럽게 나눠졌다. 그리고 나는 중간 중간 코드 리뷰를 하면서 도울 부분들을 돕고 문서 정리 및 발표 준비에 들어갔다.
이 과정에서 사실 기획을 늘렸다가 줄였는데, 진행하면서 욕심이 생겨서 매칭까지 해보려 했다가 기간이 기간인지라 결국 포기하게 되었다. (매우 매우 아쉬웠다.)
채점 자체를 실제 인트라처럼 GitHub 레포지토리를 만들어주는 쪽으로 만들면 좋았겠지만, 이 역시도 굉장히 아쉬운 부분이었다. 아래 진행 방식을 만드는데, 계속해서 레포지토리 생성 자동화가 아른거렸다...
진행 방법.pdf
494.5KB
그리고 만들어낸 발표 자료의 최종본은 아래와 같다. 초기에는 저렇지 않았고, 우리가 뭘하려고 했는지 등 세세한 정보들로 도배되어 있었다. 해당 내용으로 발표 리허설을 했다가, 멘토님께서 발표에 문제가 있다고 멘티들이 뭘했는지 명확하지 않아, 말하고자 하는 내용을 잡아내기 어렵다는 피드백을 적극 반영하여 수정하게 되었다. 이에 따라 11월 7일 막바지에 발표 대본을 수정하는 사태가 발생했다. 그런데 굳이 발표 영상을 돌려보지 않아도 지금와서 생각해보면, 이게 정말 맞는 판단이었던 것 같다. 해커톤 발표는 10분이라는 시간으로 제한되고, 이 시간은 우리가 뭘 만들어냈는지 발표하는 것으로도 부족한 시간이니... 작업 결과 위주로 발표를 구성하는 것이 더 나은 선택지가 맞다고 생각한다.
발표 자료.pdf
2394.6KB

2) 느낀 점

방송 송출에 우여곡절이 조금 있었지만, 결국 2부 3번째 순서에서 준비된 대본대로 무사히 발표를 마쳤다.
이번 해커톤이 내가 경험했던 여러 협업 중에서 가장 협업다운 협업이 아니었나 하는 생각이 든다. 비록 구현한 서비스가 자동 배포가 적용되어 있지 않고, 이슈 트래커 및 GitHub Action 미이용 등 아쉬운 것은 많았지만, 결과적으로 우리 팀은 커뮤니케이션이 정말 잘 되었다.
물론 서비스를 완성했지만 정말 간단한 기능만 만들어서 배포했기 때문에 고도화에 대한 아쉬움도 있고, 시간 제한 때문에 기술 스택 선택지도 크지 않았고, 특히 내가 Golang에 익숙하지 않았던 것 때문에 막바지엔 팀원들 도움을 많이 받긴 했지만, 정말 문제 없이 해커톤을 진행할 수 있었고, 합리적인 의사 결정이 바탕되었으며, 계획된 목표까지 성공적으로 구현을 했다는 점들이 그 무엇보다도 해커톤에서 의미있는 결과였다.
연습할 것들은 많고 여전히 공부에 전념해야 되겠지만, 짧은 기간동안 굉장히 의미있는 시간을 보낼 수 있어서 좋았고, 팀원들에게 정말 감사하게 생각한다.