-
Notifications
You must be signed in to change notification settings - Fork 4
4️⃣ 4주차 멘토링 일지
깔끔한 코드 및 구조에 대한 고민
현재 계속해서 새로운 기능이 추가되면서 코드량과 부채가 쌓여가고 있는 상황입니다. 아직까지는 어떻게든 버텨나가고 있는데 곧 유지보수가 힘들어지는 상황이 올 것 같아서 걱정이 됩니다. 또 분업을 하다보니 서로가 작업한 파일에 대한 빠른 이해를 위해서라도 리팩토링 작업이 필요할 것 같습니다. 다만 이를 위해 시간을 따로 내야 할 것 같은데 비율을 어떻게 잡아야할지, 그리고 리팩토링의 목표를 어떻게 구체화할 지에 대한 고민이 있습니다.
- 작업을 하면서 동시에 리팩토링 진행. 다만 속도는 늦어진다는 점을 감안.
- 리팩토링의 원동력에 대해 고민.
- 구현, 테스트, 리팩토링, 문서화 모두를 하나의 작업에 포함시키기.
코드에 대한 학습과 구현의 밸런스.
안되던 걸 되게 하는 데, 아직 없는 기능을 추가하는 데에 하루의 대부분을 투자하는 것 같습니다. 배워가는 상황이다보니 다른 코드베이스나 best practice들도 더 많이 찾아보면서 그리고 어떤 방법이 좋을지 직접 고민도 해보면서 성장해보고 싶은데 아직은 마음이 조급한 것 같습니다. 또 아무래도 그럴 때 느끼는 만족감이 새로운 걸 만들 때보다는 적은 것 같습니다. 이미 알고 있는 것들도 적용하지 못하고 있는 것 같은데 어떻게 하면 3주 후에 전보다 성장해 있을 수 있을지 고민이 됩니다.
- 서비스를 위한 이터레이션을 도는 것 자체가 성장.
남은 3주에 대한 고민
타겟 사용자를 데모를 사용해보는 동료 캠퍼들로 잡아야할지, 서비스를 사용할 실사용자를 고려해서 잡아야할지에 대한 고민이 있습니다. 이에 따라 저희 팀에 한정된 기간을 활용할 방법이 달라질 것 같습니다. 데모를 목표로 잡는 다면 짧은 시간 동안 사용했을 때의 편리성을 위한 기능들을 추가하게 될 것 같고 실제 서비스라고 생각했을 때에는 전체적인 안정성을 잡아나갈 것 같은데 둘 중 어디에 목표를 두어야할 지 고민이 되는 상황입니다.
- 두 가지 사이의 적절한 비율을 생각해 보기. 하나의 서비스를 내보는 것이 중요, 다만 완벽히 보안에 신경을 쓴다든가 하는 것은 프로젝트 목표와 맞지 않을 수 있다.
- 물론 피쳐만 계속 생산해 내는 것은 경계.
추가적인 피드백
- 스스로에게 너무 엄격. 스스로 좀 더 칭찬해줘도 괜찮음.
- 걱정하지 않고 잠을 잘 자기.
-
이번 주 (월~화) 작업 내용
- 이미지 업로드 API (→ Object Storage)
- Github Actions 버그 수정
- 노드 정렬기능 관련 삽질 중
-
멘토님께 학습 스프린트 마지막 주차쯤 테스트에 대해 질문 드렸던게 생각났는데, 이제 스스로 이렇게 까지 생각해볼 수 있는 레벨에 다다랐습니다 😎
- 테스트 하기 어려운
S3Client
를 직접 의존하고 있는 구조에서
- Provider를 분리하여 외부에서 주입할 수 있도록 변경했습니다
문서화 관련
- 위에꺼 구현하다가, 공식 문서랑 공식 블로그 버킷 설정과 엔드포인트 설명이 달라서 애 좀 먹었습니다.
- 직접 삽질해보니까 너무 어이가 없었습니다. 노가다는 뛰었지만 내 잘못이 아니었다니
- 문득 ‘문서화의 책임은 누구에게 있는가?’ 하는 고민이 들었습니다. 저희 팀도 구현은 빠르지만 (저 빼고는 잘 하고 계신 것 같긴 하지만) 문서가 잘 적히는 편은 아닌 것 같기도 하고요.
- 학습과 구현의 밸런스를 맞추는 과정을 연습했듯, 문서와 구현도 직접 시간을 투입해가며 밸런스를 잡아야 하는 걸까요?
- 정말 큰 회사 같은 경우는 Technical Writer 직무가 따로 있는 것도 보았는데, 이런 경우는 본인이 구현하지 않은 부분에 대해 문서를 작성하게 되는건가요?
- 현업에서의 문서 작성 프로세스 자체가 궁금하기도 합니다.
> 팀 차원에서 강제할 수 있는 방법 → 완료 기준을 테스트 코드 & 문서로 잡기
학습과 성장을 위해서!
*일정을 잡을 때
>
> - 태스크 = 구현 + 테스트 + 문서
>
> https://www.perplexity.ai/search/python-doctest-yi-javascript-t-Ed40Y2BaRKSRcLgPrCMHig → 문서 + 테스트 + 사용법을 한 큐에
>
노드 정렬기능 관련
- 지난 주 데모를 마치고 다른 캠퍼들에게 데모 링크를 배포해보며 직접 피드백을 받았었습니다. (폭발적인 반응이 있었습니다 ㅎㅎ)
- 그 중 일부 피드백들을 기능으로 들여오려고 하는데, 하나가 바로 ‘노드 정렬’ 기능입니다.
- 실시간으로 여러 명이 하나의 캔버스에서 노드를 생성하고 배치하다보면, 노드끼리 겹치거나 어지럽게 배치된 경우가 있는데
- 버튼 한 번으로 깔끔하게 배치 시켜주는 기능을 원하는 사람들이 꽤 있었습니다.
- 이를 구현하기 위해 다방면으로 조사해보고 설계 해봤는데, 제가 내린 결론은 크게 2가지 입니다.
1. 백엔드 단에서 `graphviz` 라이브러리를 통해, 포크 후 재정렬 계산을 돌린다
2. 프론트엔드 단에서 `ELKJS` 라이브러리를 통해, WebWorker로 재정렬 계산을 돌리고 위치가 변경된 노드들만 백엔드로 갱신해달라고 요청한다
- 2번을 직접 프로토타이핑 해보고, 어느 정도 동작함을 확인했습니다.
- 그런데 현재 FE 분들에게 업무가 과장되어 있는 상태라 뭔가 선뜻 부탁드리기 좀 그러네요. 괜히 제가 건들였다가 코드베이스를 오염시키는 느낌도 있고…
- 1번으로 진행하기에는 오히려 여러 명이 재정렬 요청을 했을 때, 서버에 부하가 심할 것 같아서 배제하려는 상황입니다.
- 기술적으로 고민이 되는 상황이기도 하면서, 협업 상황에서 `나보단 다른 사람이 더 잘 해낼 수 있을 때` 부탁하는 과정 자체도 쉽지 않은 것 같아서 고민입니다.
라이브러리 의존성
- 하드 스킬 어필을 위한 도전 요소
- 프로젝트로 어필할 주제 → 제일 빠르게 deploy해서 사용자 피드백을 받고 이를 통해 개선하는 경험 등
⇒ 이런식으로 가면, 라이브러리를 사용한 것 자체가 합리적인 판단
→ 나라는 사람이 제대로 담기게끔 의사결정 (Why & How ⇒ What)
지금의 고민
-
기술적으로 도전하는 기분을 못느낌 → 그래서 DB, 캐시 쪽 성능 최적화를 생각 중
-
어떻게 할지는 방향성을 잡았는데, 좋은 방향성이라고 생각하시나요? 그 둘의 성능을 어떻게 비교하나요?
a. DB 개선 (Foreign Key 없애고 서비스 레이어에서 조인 기능 구현, 대체키 추가하고 index 넣기)
b. 캐시 구현 (소켓 - 캐시 - PostgresSQL DB) 사이에서
캐시
- Client에서 chunking (직접 구현) → 관리할 요소 생김
- WAS가 다 받고, 공유하는 Queue에다가 몰아놓고 스케줄러가 돌아가면서 처리 (직접 구현)
- message Queue 같은 전문 처리장치 (라이브러리)
다른 기술적 도전
- 클라이언트가 보내는 변경사항은 스냅샷의 재료들, 그걸 합치면 스냅샷, 그걸 백엔드에서 머지?
- pdf export → 마크다운에 비해서 pdf는 cpu를 많이 쓴다, WAS가 cpu blocking이 됨, export 끝날때까지 어떻게 빨리 block없이 응답?
- dx tooling? → 노가다성 작업? typescript interface로 schema, 모노레포, cli에서 명령어를 입력하면 interface에서 읽어서 클라이언트를 만들어줌
- 프런트엔드 입장에서는 클라이언트 대신 스키마
admin 만들기 → 로그인 뿐만이 아니라 유저 권한 관리 (최초의 슈퍼유저 → 다른 admin ) DB, 캐시 → admin 기능 → 문서 내보내기 → 검색 기능
-
빠르게 release하게 사용자 feedback을 돌면서 iteration을 많이 돌것 → 이것도 좋은 방향일 수 있다
-
문서화를 통해 이해도를 높일 수 있었다 → 어필
-
release를 통해서 피드백을 실제로 발견해서 이런 문제들을 직접 해결했다
-
의사결정을 내릴 때 자기가 묻어난 판단을 내리는 것이 필요
- ex) 라이브러리 vs. 프레임워크 선택 이유
- 이기적인 목표더라도 결과적으로는 팀에 기여할 수 있게
-
프런트엔드: 리액트 → 이게 이거구나 이해할 정도로는 공부하는게
→ 필요한 부분 읽어보기
성능 비교 - 실험환경 구축: cpu 다른데 돌고있지 않게하기 - e2e 테스트로 스트레스 거치기 → 가장 실제에 가까운 테스트 하기 - 프런트엔드가 문서를 보내는 것을 시뮬레이션을 보내서 캐시 O, X 비교하기 (worker 띄워서) → CPU사용량 등 프로파일러 돌리면서 체크한다 - db에 직접 보내는 것이 아니라 실제환경은 WAS를 거쳐서 들어오는데 TypeORM에 mysql adapter이 구릴수도… 그 테스트로 판단을 한다
- 백엔드에서 캐시를 어떻게 할지 가장 먼저 의논해야될듯? 인메모리 스레드에서? 레디스? 카프카?
- 캐시 안쓰고 해결방안 찾기? 메모리에 일정용량까지 큐에 쌓다고 한번에 보내기, WAS가 deploy됐다가 접속안될때는 큐에 쌓아놓고 다시 시도 → but WAS가 한대일때 기준, 로드밸런스가 분산시켜준다면? 그러면 merge가 상태가 이상해질것
.env 파일 관리
현재 저희는 local에서 프론트와 백엔드 서버를 띄워서 테스트를 하고 있고 개발 서버와 상용 서버를 운영하고 있습니다.
그리고 CI/CD를 구축하였고 .env 파일은 민감한 정보가 담겨있기 때문에 github action secrets을 통해 안전하게 보관하는 중입니다.
그러다보니 .env 파일에 변경 사항이 생기면 다음과 같은 과정을 거치게 됩니다.
- .env파일의 변경 사항을 팀원들과 공유합니다.
- github action secret의 개발 서버 용 .env를 수정합니다.
- github action secret의 상용 서버 용 .env를 수정합니다.
- 로컬 저장소의 .env를 수정합니다.
저는 이 과정이 굉장히 번거롭고 간혹 갱신이 잘 이루어지지 않아서 서버 실행에 실패하는 경우도 종종 있었습니다.
혹시 이 방법이 최선일까요?
멘토님께서는 .env와 같은 민감한 환경 변수들을 어떻게 안전하게 관리하면서 팀원들과 공유하시는지 궁금합니다.
데이터 구조 고민
현재 저희 프로젝트는 yjs 라이브러리를 사용하여 실시간 동시 편집을 구현하고 있습니다.
yjs에서는 Y.Doc이라는 document를 제공해주고 여기서 동시 편집 충돌 문제를 알아서 해결해주고 있습니다.
또한 서버에서는 이 Y.Doc이라는 document의 변경 사항을 감지할 수 있습니다.
하지만 Y.Doc의 값은 메모리에 저장되기 때문에 영구적으로 데이터베이스에 저장할 필요성을 느꼈습니다.
지금은 서버에서 문서의 변경 사항을 감지할 때마다 데이터베이스의 테이블을 갱신하는 방식을 사용하고 있는데 여러 명이 동시에 편집을 하게 되면 엄청난 양의 쿼리가 발생하여 순식간에 서버가 꺼져 버리는 이슈가 발생했습니다.
이러한 현상을 해결하려고 다음과 같은 구조를 생각했습니다.
변경 사항을 감지할 때마다 갱신하지 않고 일정한 주기로 갱신한다.
일정한 주기로 Y.Doc의 값을 가져와서 데이터베이스에 저장하는 방식입니다.
변경 사항이 발생할 때마다 쿼리를 날리지 않기 때문에 데이터베이스의 부하가 확실히 줄어듭니다.
그런데 일정한 주기로 실행하는 시스템을 구축해야 하고 저희 개발자의 관리 요소가 더 늘어날 것 같아서 이 방식을 도입하기가 조금 꺼려집니다.
또한 특정 시간마다 저장하는 시스템을 도입한다면 그 사이에 발생하는 변경 사항을 영구적으로 저장하지 못 하는 현상도 발생할 것 같습니다.
결국 저희는 데이터베이스의 부하를 줄이면서 변경 사항을 놓치지 않고 제대로 데이터베이스에 반영하는 시스템을 구축하고 있는데 적절한 방법이 떠오르지 않는 상황입니다.
혹시 멘토님께서 추천해주시는 구조가 있는지 궁금합니다!
항상 질문이 어렵습니다 ㅠㅠ
프로젝트를 하면서 생기는 고민들은 예를 들면 “useEffect
가 많아짐에 따라 성능에 문제가 생기지 않을까?“, “컴포넌트의 볼륨이 너무 크나? 그러면 어떻게 줄이면 좋을까”와 같은 내용인데 이런 것들은 제가 해결해야할 문제라서… ㅠㅠ
리팩토링 관련 질문
-
현재 기능들을 추가하는 데 집중하느라, 코드 리팩토링을 많이 못한 거 같습니다..
하루 날 잡고 같은 분야의 팀원과 리팩토링을 진행하고 싶은데 괜찮은 방법일까요..?
-
기능 구현은 각자 맡은 것을 독립적인 브랜치에서 작업을 하다가, 만약에 충돌이 나도 수동으로 해결해주면 될 것 같은데, 리팩토링의 경우 전체적으로 코드를 건드릴 일이 많을 것 같아서 걱정이 됩니다.
팀 프로젝트에서 리팩토링은 어떤 식으로 작업을 해야할 지 궁금합니다!!
프로젝트 구조 관련 질문
현재 저희 프로젝트 구조는 역할별로 ex) /components
, /api
, /hooks
, … 와 같이 구분되어 있습니다. 그러나 이런 프로젝트 구조는 체계적이지 않다는 생각이 들었습니다.
(components
폴더만 해도, 이를 어떻게 하위 폴더를 분리해야 할지 모르겠고, 일관된 기준도 현재 없는 상태입니다.)
프로젝트 특성상 여러 페이지보다 특정 기능(에디터, 노드 캔버스, 실시간 작업 등)에 초점이 맞춰져 있어 기능 단위로 구조를 나누는 방안을 고려 중입니다.
이 과정에서 FSD 아키텍처를 알게 되었는데, 이에 대한 의견이나, 모르신다면 체계적인 프로젝트 구조화 방법이 궁금합니다.
학습 관련 질문
3주차, 4주차 내내 CRDT 라이브러리인 Y.js와 웹소켓을 이용하여 동시 편집 기능을 구현했습니다.
Y.js와 같은 CRDT 라이브러리에 대해 깊게 공부하는 게 어떤 의미가 있지? 라는 생각이 들어서 간단하게 흐름 정도만 알고 있는 상태입니다.
물론, CRDT가 어떤 기능이고, 어떤 원리로 돌아가는지 학습하는 것은 의미가 있다고 생각을 합니다.
이런 라이브러리를 깊게 학습하는 게, 나중의 포트폴리오나 성장에 도움이 될지 궁금합니다…
⚓️ 사용자 피드백과 버그 기록
👷🏻 기술적 도전
📖 위키와 학습정리
✏️ 에디터
Novel이란?
Novel 스타일링 문제
에디터 저장 및 고려 사항들
📠 실시간 협업, 통신
Yorkie와 Novel editor 연동
YJS, Websocket, React-Flow
YJS, Socket.io
WebSocket과 Socket.io에 대해 간단히 알아보기
YJS 가이드 근데 이제 Socket.io를 곁들인
🏗️ 인프라와 CI/CD
NCloud CI CD 구축
BE 개발 스택과 기술적 고민
private key로 원격 서버 접근
nCloud 서버, VPC 만들고 설정
monorepo로 변경
⌛ 캐시, 최적화
rabbit mq 사용법
🔑 인증, 인가, 보안
passport로 oAuth 로그인 회원가입 구현
FE 로그인 기능 구현
JWT로 인증 인가 구현
JWT 쿠키로 사용하기
refresh token 보완하기
🧸 팀원 소개
⛺️ 그라운드 룰
🍞 커밋 컨벤션
🧈 이슈, PR 컨벤션
🥞 브랜치 전략
🌤️ 데일리 스크럼
📑 회의록
1️⃣ 1주차
킥오프(10/25)
2일차(10/29)
3일차(10/30)
4일차(10/31)
2️⃣ 2주차
8일차(11/04)
9일차(11/05)
11일차(11/07)
13일차(11/09)
3️⃣ 3주차
3주차 주간계획(11/11)
16일차(11/12)
18일차(11/14)
4️⃣ 4주차
4주차 주간계획(11/18)
23일차(11/19)
24일차(11/20)
25일차(11/21)
5️⃣ 5주차
5주차 주간계획(11/25)
29일차(11/25)
32일차(11/28)
34일차(11/30)
6️⃣ 6주차
6주차 주간계획(12/2)
37일차(12/3)