[우아한테크코스 6기] 레벨 3: 4주 차 회고

,

언제부터 회고를 주중에 쓰고 있을까,, 바쁜 나날 지나가고 한숨 돌리며 한 주를 돌아봐야 했다. 누워있느라 너무나 나태해진 나.. 주말만은 나를 놔둬 🥹

이번 주에도 많은 일이 있었지만, 기억에 확실하게 남는 건 데모데이 이야기다. 벌써 4주가 지났지만 그동안 제자리걸음을 하게 된 이야기, 우리가 집중해야 할 것을 놓쳤던 이야기들을 풀어보려고 한다. 리뷰미 화이팅 👏

💿 CI/CD, 어떻게 하는 건데

지금까지는 GitHub Actions를 활용해 CI/CD를 활용했다. 나아가 Self-Hosted runner를 활용해 GitHub Actions로부터의 배포도 진행됐다. 설정을 성공적으로 마무리하니 PR 머지와 함께 배포가 진행됐다. 성취감과 뿌듯함도 있었지만 딸려오는 질문들이 밀물듯이 들어왔다. 우테코 내부에서는 80/443 inbound만을 허용하는데 어떻게 접근이 가능한 것인가? GitHub Runner 말고 다른 방식으로 CD를 할 수 있는가? 와 같은 여러 질문들이 들어왔고, 이와 관련한 삽질도 조금 해 봤다.

우선 GitHub Actions를 활용한 CI/CD는 이 포스트에서 확인할 수 있다. 이제 내가 궁금한 건 외부에서 신호를 받는 형태일 텐데, 어떻게 Self-hosted runner가 동작하는가? 가 첫 번째이다. 이에 대한 가설은 80/443 포트를 사용한다는 것이다. 하지만 우리가 80 포트를 직접 스프링에 연결해 두었으니 (빠른 구현을 위해 어쩔 수 없었다 🥲) 80은 아닐 것이고, 자연스레 443 포트로 눈길이 돌아갔다.

443을 통해 Inbound를 받는다고 한다면, 또다른 문제가 발생한다. 추후에 443 포트를 통한 Https 통신을 할 수 없다. Runner가 이미 듣고 있기 때문이다. 여기에서 오잉? 왜 되지? 라는 생각이 들어서 Runner 관련 문서를 찾아보기 시작했다. ‘GitHub Runner 443’이라는 키워드로 깃허브 공식 문서를 들춰볼 수 있었다.

The self-hosted runner uses an HTTPS long poll that opens a connection to GitHub for 50 seconds, and if no response is received, it then times out and creates a new long poll.

The connection between self-hosted runners and GitHub is over HTTPS (port 443).

Since the self-hosted runner opens a connection to GitHub.com, you do not need to allow GitHub to make inbound connections to your self-hosted runner.

Inbound가 아니었다는 것에 1차 충격이고, polling을 통해 50초간 대기- 끊고 다시 연결을 반복한다고 한다. 여기에서 우선 첫 번째 호기심 해결!

두 번째로는 다른 CI/CD 툴이 존재하는가? 였다. 우테코 내부에서 aws 관련 문의를 받는 슬랙 채널에서 조이썬이 CodePipeline에 대해 이야기하는 것을 봤다. CodeBuild / CodeDeploy를 통해 한 번에 CI/CD를 한다고 한다 🤨 호기심에 이 쪽도 파 봤는데, 결론적으로는 GitHub Actions와 마찬가지로 CodeDeploy Agent를 설치한다는 점, Runner와 거의 똑같이 동작한다는 점에서 나를 충분히 설득시키지 못했다.

🪢 연관관계 설정하기

구현하면서 서비스가 뚱뚱해진다는 생각이 들었고, 이에 백엔드 네 명이서 머리를 맞대고 자바에서 어떤 방식으로 구현했을지를 상상하며 연관관계를 맺었다. 가령 ‘리뷰 그룹’에는 ‘리뷰’들이 저장될 테니, List<Review>로 가지고 있는 것이 타당하다고 보였고, 전체적인 Java 코드상에서는 의존성 순환 문제가 발생하지 않았었다.

그냥 자바는 말이 쉽지..

진짜 재앙은 JPA를 붙이면서 시작됐다. 일반적으로 객체 간의 의존성은 우리가 생각하는 대로 연관관계를 맺지만, 관계형 데이터베이스에서는 그런 것을 지원하지 않았고, 1:N 관계라면 N 쪽에 외래 키를 가지고 있어야 했다. ‘객체 형식으로 짜야지!!’ 라고 생각하다보니 결국 모든 연관관계를 Pojo와 같이 인스턴스 형태로 들게 되었다. 양방향 연관관계가 들어오면서 생성할 때 꼬이기 시작했고, 결국 NPE까지 맞이하게 되었다.

레벨 1, 2에서 배운 것은 무엇이었을까? 객체를 기반으로 서로 이야기하는 것이 더 좋은 코드가 아닌가? 배운 내용에 대해서 곧바로 부정하는 결과가 눈 앞에 펼쳐졌으니, 코드가 발전하기는커녕 수렁에 빠지고 있었다. 아니, 그보다 좋은 코드는 무엇인가? 객체지향이 좋은 코드가 아닌가?

아니었다. 주객이 뒤집혀도 단단히 전도됐다. 우리는 좋은 코드를 만들기 위한 수단으로 객체지향을 활용한 것이지, 반대로 생각했으니 그에 대한 대가가 상당했다. 테드의 추천으로 100분짜리 우아한 객체지향이라는 세미나를 시청하게 되었는데, 그곳에서도 ‘때로는 객체지향보다 절차지향이 나을 때가 있다’고 이야기한다.

연관관계를 자바 세계에서만 고려해도 좋지만, DB가 들어오는 것을 무시할 수는 없다. 생명주기가 정확하게 일치하는 친구들끼리는 연관관계를 강하게 (영구적으로) 맺고, 그렇지 않은 친구들은 오히려 id를 들고있게 하는 것이 더 낫다는 이야기다.

생명주기의 일치는 단순히 맥락에 그치지 않는다. 어떻게 보면 <리뷰 그룹>과 <리뷰>는 생명주기가 같아 보이지만, 리뷰 그룹이 생성되는 것과 리뷰가 생성돼 그룹에 추가되는 것은 분명 다른 시간축에 존재한다. 도메인 내부에 인스턴스가 생기는 것은 항상 유의하자. 그 자체로 발전하거나 재사용될 수 없음을 인지해야 한다. 물론 도메인과 엔티티를 따로 볼 것인지에 대한 논의도 선행되어야겠지만.

결국 이 코드를 어찌저찌 완성해 데모데이에 발표하기는 했지만, 코드 퀄리티에서도 그렇고, 뒤에 이야기할 핵심 기능에 대해서도 그렇고 이야기할 내용이 많아 다음 주로 미루겠다.

🤨 데모데이, 우리가 집중해야 할 것

금요일 데모데이가 진행됐고, 예상은 어느정도 했지만 그보다 쓴 소리들이 우리를 맞이했다. 어떻게 보면 ‘핵심 기능에 대한 피드백’을 못 받은 것이 가장 컸다. 이전 데모데이에서도 기능보다는 우리가 어떤 서비스를 제공하고 싶은가? 에 대해 초점을 맞췄다면, 이번에도 그 뿌리는 같았다. 결국 해결하고자 하는 문제를 긁어주지 않았다.

‘리뷰’라는 것을 통해 자신을 알아가는 서비스. 도메인이 너무나도 어렵다. 자신을 알아가고 성장을 하기 위해서는 좋은 리뷰가 필수다. 좋은 리뷰는 공짜가 아니다. 다른 팀원들과의 유대감, 프로젝트 내에서의 끊임없는 소통으로부터 점점 올라온다고 생각했다. 우테코에서 당연하게 생각했던 리뷰 문화가 외부에서 통할 것이라고 생각한 것이 짧았다.

우리의 결론은 ‘사용자가 리뷰 사이클을 느낄 수 있도록 가장 빠르게 출시하고, 피드백 받기’가 되었다. 로그인, 모아보기와 같은 것은 부차적인 내용이었다. 리뷰를 통한 나를 돌아보기가 전제되지 않는다면 사용자가 우리의 서비스를 이용하지 않으리라.

3차 스프린트 때 이런 걸 할 거예요~ 라는 것들도 모두 무너졌다. 4주가 지났지만 우리는 다시 출발선에 서 있다. 그럼에도, 앞에 어떤 장애물들이 있는지는 파악을 해 뒀기에 전보다는 빠르게 나아갈 수 있을 것이라고 믿는다. 리뷰미 팀 너무너무 고마워요 🥲

흔들리지 않으리라 다짐했다. 확실하게 색깔을 잡았다고 생각했지만 코치들의 의견에 흔들리는 것을 보니 참 우습다.

핵심 기능에 집중해야하는 것 아닐까? 계속 급하다고 생각해 리뷰와 관련된 고민은 하지 않고, 얼렁뚱땅 완성해 원하는 피드백을 받지 못했나? 팀 프로젝트의 목표는 ‘개발’이라는 일차원적인 것과는 거리가 멀었다. 사용자가 어려움을 겪는 것을 관찰하고, 이를 해결하기 위한 서비스를 제공하는 것이 우선시되야 함을 늦게 알아챘다. 코치들은 이미 방향타를 돌렸지만 눈치채지 못했다.

우리가 해결해야 하는 문제가 어려웠다. 문화를 선도하거나 신뢰성있는 리뷰를 위한 것보다는, 자기PR과 메타인지를 목표로 잡았다. 그럼에도 양질의 피드백은 중요했다. 본질을 또다시 놓쳤고 이는 불필요할 수 있는 회의와 작업들로 이어졌다. 흐린 목표가 팀이 나아가지 못하게 방해한다는 걸 몸소 겪었다.

어떻게 하면 좋은 피드백을 받을 수 있을지, 내부적으로 많은 시도를 해봐야 한다. 구체적이고 그릴 수 있는 질문들, 특정 상황을 떠올리게 할 수 있는 질문들. 데모데이 이전에 핵심 기능을 빠르게 완성해서 (피드백) 데모데이를 진행하면 어떨까? 코치를 이용하자. 아쉬운 만큼 데모데이 한 번 더 하는 게 낫겠다.

데모데이 회고

🥲 이번 주는요

돌아돌아 다시 제자리. 이런 회의에 지치고 힘든 것을 모두 공유하기에 더욱 소중한 팀이다. ‘나 힘들어’라는 이야기를 보통은 삼키는 편이지만, 팀 내부에서는 모두 털어두는 분위기라 편하다. 나만 느끼는 답답함이 아니고, 나만 느끼는 어려움이 아니니까 더 가까워질 수 있다고 생각했다.

다른 팀들도 비슷한 내용으로 어려움을 겪었을까 궁금하다. 혹시라도 누가 이 블로그를 보고 있다면 팀 상황을 공유해주면 좋겠다 ! (물론 이야기할 수 있는 정도만)

Categories