소소하게 작성하려 했던 글이 생각보다 길어졌습니다..🎃🎃
노션에 5주간 프로젝트를 하면서 작성한 기술적 고민과 과정들을 적어보았습니다. 혹시 읽어보시다가 이건 아니다!! 싶은 지점들을 알려주시면 너무너무 감사드리겠습니다..!!
https://markchck.notion.site/4e2ac5889a1c48b2ba5f7bdb98977df3
내일이면, 5주간 진행되었던 '나만의 무기' 프로젝트가 종료된다. 왠지 내일이 지나면, 면접 준비하랴 코테 준비하랴 바쁠 것 같아 기록을 남기지 않을 것 같다. 마지막 날 하루 전 5주간의 기록들을 적어보려고 한다.🦾🦾
프로젝트를 시작했을 때의 '나'로 돌아간다면, 이건 이렇게 하지 않을텐데 싶을게 많다. 그만큼 5주라는 시간을 천천히 톺아보면, 개발, 협업, 멘토링 등 소중한 경험이 내 앞에 펼쳐졌다. 프로젝트를 시작했을 때로 돌아간다면 나에게 해줄 말들을 기록해보자.
작심5일이 되어버린 일기📕 그래도 개발 기록은 꼼꼼히 남겨놓았으니 잘 정리해야지!
우리는 '몸으로 말하기 게임'을 webRTC👨👨👧👧를 활용하여 웹상에서 다같이 즐길 수 있는 프로젝트로 만들고자했다.
(대략 이런 느낌의 3 VS 3 웹 게임👨💻👩💻을 만들었다)
첫 기획 회의 당시 게임에서 보여줄 3가지 기능을 구현하기로 했었다. 중요한 순서대로 몸으로 말하기, 카드뒤집기, 움짤만들기. 팀 내에서 합의가 되었던 사항은, 만약 메인 게임(몸으로 말하기)이 완성되지 못 한다면 중요도가 낮은 순으로 드랍하기로 했었다.
기획 의도와 다르게 어긋났던 부분은 SFU 방식의 webRTC를 위해 OpenVidu 라이브러리를 사용하는 지점이었다. 라이브러리를 가져다 쓰는 것이었기에 소요 시간을 2일 정도로 생각했던 부분이 약 5일 정도의 시간을 소비하게 되었다. 원인을 되짚어보면 nginx가 외부에서 들어온 요청에 따라 내부 port 요청을 어떻게 보내는지, webRTC를 이용하기 위해선 http가 아닌 https를 사용해야한다는 것 등을 몰랐기에 발생한 일이었다.
(최종적으로 Nginx를 통해 오픈비두도 사용했고 Scale-out을 했다)
시작이 꼬이면서 마음이 급해졌고, 예정되어있던 첫 데드라인까지 3가지 중 단 한 가지도 시연 가능한 수준으로 구현하지 못 했다.😂 구현하지 못 한 이유를 꼽자면, 앞서 이야기한 것처럼 버퍼를 크게 잡지 않은 것도 있지만 생각보다 게임을 구현하는데 (2명의 프론트) 인원수에 비해서 구현해야 할 프론트 작업이 많았다. 팀 내부 회의를 통해 백엔드 인원들도 프론트 작업을 하기로 했고 백엔드 3명이 카드 뒤집기 게임 구현을 위해 함께 React를 시작하게 되었다.
여기서, 문제가 발생했다. React의 기본이라 할 수 있는 useState, useEffect 등이 무엇인지 모르는 상황에 일단 돌아가는 코드(개발에서 돌아가는 코드를 짜는 게 중요하긴 하지만..!)를 만들겠다는 마음만 급해져 chatGPT에게 모든 것을 물어보는 상황에 이르렀다.
(React에 대한 지식 없이 chatGPT에 무턱대고 물어보던 최악의 코딩)
chatGPT copy and paste -> npm run build -> npm start -> console창 확인을 수없이 반복했다. 덕분에 chatGPT에게 내가 원하는 코드를 얻기 위해서 어떻게 질문해야 하는지, 한글과 영어를 섞어서 질문을 하면 2번째 질문부터 한글로 질문해도 영어로 답을 해준다던가(이런건 왜...) 등 개발에 대한 지식을 쌓았다기 보다 chatGPT와 서로를 심도 깊게 알아보는 시간(?)을 보내게 되었다.
이 과정에 배운 것도 있었지만, 많은 회의감을 느끼게 되었다. (후술하겠지만 이렇게 만들어진 코드 때문에 이걸로 약 2일치 코드를 롤백하게 된다..😂😂) 더 빠른 길을 찾아가겠다고 뭔가 열심히 하지만 사실 아무 의미없이 배회하는 느낌? 데드라인에 급급해져 생각하며 하는 코딩이 아닌, 코딩에 맞춰 생각을 하고 있는 나의 모습이 너무 부족해보였다. 정글에서 5개월간 주말, 공휴일도 없이(1월23일은 설이다..😃) 하루에 순수 개발공부만 16~18시간하며 배운 건 이런게 아니었는데..
이렇게 부정적인 감정에 젖어 지쳐있을 때, 너무나 감사하게도 협력사 설명회 때 현업 개발자 분들께 질의를 할 수 있는 시간이 있었고 멘토님이 조언이 되는 말씀들을 해주셨다.
(멘토님이 해주신 이야기들. 그 외에도 항상 질문을 해주셨다)
멘토님께 가장 감사했던 부분을 꼽자면, 끊임없이 질문을 해주셨다는 것이다. 구현에 급급해져 놓쳤던 부분들에 질문을 남겨주신 덕분에 답을 고민해보는 시간을 다 같이 갖게 되고, 그에 대한 답을 찾고 나면 짜놓은 코드의 문제점을 발견하기 쉬웠다. 사실 이 과정은 정글에서 체득한 부분이라고 생각했었다. 문제가 발생하면, '왜?'를 찾아가는 과정. 2달동안 C언어로 RBtree, malloc-lab, pintos를 풀어나가며 문제의 원인을 찾는 과정을 익혔다고 생각했다. 그러나 프로젝트가 시작한지 2주도 안되어서 멘토님이 말씀해주신 것 중 '구현'에만 매몰되어 난관이 무엇인지, 사고의 과정, 아이디어 모두를 놓치고 있었다.
(정글의 WEEK05 ~ 13 때 배운 건 어디에 두고 왔는가!!)
그렇다면, 어떻게 할까? 아마, 이전까지 구현에 급급했다면 또 chatGPT에 끊임없이 코드를 던지며, 답을 얻으려 했겠지만..!
카드 뒤집기 게임을 구현하다보니, 마지막에 카드가 한 장이 남아 동시에 여러명이 카드를 클릭하는 순간이 발생했다. 그 탓에 백엔드는 프론트로부터 수없이 많은 요청을 받게 되고 또 그 많은 응답을 다시 프론트로 내보내 🔑Lock을 구현할 필요가 있다는 걸 생각하게 된다!
(우리 발표 ppt, Race Condition이 발생한다!)
(자세한 개발 과정은 깃과 노션에 정리해놓았습니다 😊)
처음에는 카드뒤집기 score Lock을 list 형태로 관리했다. 그런데 웹 상황에 따라 락이 정상적으로 동작하지 못 해 득점이 중복되거나, 점수는 제대로 산정되더라도 카드가 뒤집히지 않는 경우가 있다는 2가지 문제가 있었다.
이에 대한 원인으로, 카드 클릭 시 해당 카드에 대한 lock을 탐색하는 시간이 O(n)이기 때문에 낮출 필요가 있다고 판단했다. 결국 lock을 dictionary 형태로 관리하기로 하였다. 추가로 카드가 뒤집어지지 않는 현상은 score에서 카드가 뒤집어 지는 것과, 점수 산정 2가지를 한 번에 emit하지 않고 '뒤집기여부'라는 lock을 따로 만들고 소켓 emit을 분리하여 문제를 해결하였다.
그럼에도 여전히, 특정 상황에 락이 제대로 작동하지 않는 상황이 존재했다. 많은 요청이 들어오면 아직 락이 처리가 되지 않은 상황에 의도하지 않게 코드가 진행되기 때문이라고 판단했다. 이를 해결하기 위해 async_Lock을 사용하여 들어오는 요청을 큐(대기열)에 넣고 임계구역 작업이 끝나면 순서대로 처리할 수 있게 코드를 수정했고 의도한대로 작동했다.
(🔑락까지 구현한 결과물..!)
어떻게 보면, 이렇게 문제를 찾고 원인을 찾아 해결하는 과정이 '당연한 거' 아니야? 라고 할 수 있지만 그 과정을 놓치고 있었다. 그럼에도 다시 방향을 잡아주신 멘토님과 함께해주신 팀원분들께 너무 감사드립니다!!
앞서 언급했지만, React를 하나도 모르는 상황에 코드를 짜고 CSS작업까지 담당했다. 물론 지금도 정확히 리액트를 이해했다고 하기 어려운 레벨이지만, 어느 정도 코드를 작성하며 흐름은 잡을 수 있는 단계였고 혼자 npm run start를 하면 내가 원하는 방향으로 작동하여 매우 흡족했다.
그런데 문제는 시연 하루 전 6명이 다같이 플레이 하며 발생했다. 분명 혼자서 접속할 때는 문제가 없었던 코드가 접속하는 사람 수가 늘어나니 '크롬 응답 대기😲'창이 뜨며 진행되지 않는 것이었다. 새로운 기능을 추가한 것이 아니고 각 기능들이 뼈대는 잡혀 있는 상황에 CSS작업밖에 덧붙힌게 없는데 응답을 받을 수 없으니 답답한 노릇이었다.(console 창에 어떤 에러도 찍히지 않고 그냥 크롬이 종료된다)
시간이 촉박하고 모든 팀원이 작업한 코드가 합쳐진 탓에 어떤 코드부터 떼놔야할지 막막했다. 결국, Git commit 한 지점을 하나하나 찾아가 돌려보며(이분탐색했다..) 어느 지점에 코드가 터지는 문제가 있는 지 찾아보았다.
여기서 우리 팀이 잘했던 것 중 하나는 깃 컨벤션을 정해놓고, 커밋을 할 때 양식을 지켜 깃 로그를 확인하기 쉬웠다는 것이다!!
(우리 팀의 깃 컨벤션.. 이걸 어디에 쓰나 했다. 🎵그게 나야 둠빠둠빠 뚜비두밤 바로 나야🎵)
찾고 보니, 미니 게임에서 본 게임으로 넘어갈 때, 누수가 발생하여 메인 게임이 들어가면 참지 못한 크롬이 응답을 종료하는 것이었다.
중간 시연이 몇 시간도 안 남은 상황에 코드를 재작성하기가 어렵다고 판단하여, 내가 작성한 코드들을 주석처리하고 중간 시연에는 내가 작성한 모달창과 효과음 등등은 넣지 못 했다. 최종 시연이 아니었음에 그나마 다행이지 만약 최종 시연이었다면.. 상상조차 하고 싶지 않다...
5주 전에 내가 한 번 읽으면 좋을 글인거 같다!
정말 힘들었지만 재미가 있었다.
앞으로도 더욱 많은 프로젝트를 해보고 싶다 ㅎㅎ
정글 모두 고생했어요 앞으로도 화이팅입니다!!