시행착오

Oak_Cassia·2023년 3월 28일
0
post-thumbnail

시행착오, 해결, 느낀 점

Boost.sio 에서 io_context.run()을 멀티 스레드에서 호출하려고 했는데 run() 이 작업이 없으면 곧바로 반환을 해버려서 비동기 작업 처리를 못함

  • 공부했던 것과 사용한 라이브러리의 버전이 달라서 작동하지 않았다.
  • 해결 방법
    • 최신 버전에 대한 추가적인 학습 후 executor_work_guard를 사용하여 해결
  • 느낀 점
    • 개발 전에 기술을 분석해야겠다. 최신 버전은 무엇인지, 학습한 버전은 무엇인지 확인 후 준비한 버전을 사용해야겠다.

하나의 작업을 끝내고 다음 작업을 정하는 것에 시간 소모가 큼

  • 해결 방법
    • 투두리스트에 구체적인 작업 작성 후 새로운 작업이 생기면 업데이트
    • 서비스 분석 후 필요 기능 정리
    • 서비스 흐름 분석 후 작업 순서 파악
  • 느낀 점
    • 막연히 개발을 할 때는 몰랐는데 시스템이 커지고 각 부분이 유기적으로 결합된 서비스를 개발하다 보니 작업의 순서가 중요하다고 느꼈다.
    • 설계 단계에서 무엇을 만들지만 생각하지 말고 어떻게 만들지도 같이 생각해야겠다.

멀티스레드에서 동기화를 위해 락 사용시 성능 저하

  • RoomManager 클래스에서 LOCK을 걸고 room 객체를 찾은 뒤 그 상태에서 room 안의 _users 변수에 접근하기 때문에 긴 시간 LOCK이 걸림

  • 해결 방법

    • 방을 찾는 과정에서만 Lock을 사용한다. 방을 찾으면 락을 해제하고 포인터를 반환한다.
  • 느낀 점

    • 로직을 변경하여 문제를 해결할 수 있다는 사실을 직접 겪었다. 개발 경험이 많을 수록 효율적인 로직을 작성할 수 있을 것 같다.

커밋 주기가 길어 많은 양이 한 번에 올라가 알아보기 힘듦

  • 커밋 메시지의 형태, PR의 형식에 대한 규칙만 존재하여 하나의 커밋에 얼만큼의 데이터가 담겨야 하는지 정해지지 않았다.
  • 느낀 점
    • 커밋할 내용, PR의 길이와 어떤 단위, 주기로 커밋을 할지 규칙을 정해야겠다.

유니티 네트워크 코드 구현이 늦어져 전체적인 개발 일정 차질

  • 느낀점
    • 개발 전에 필요한 작업들의 관계를 파악하고 임계경로를 알아둬야 할 것 같다. 결국 완성되기는 했는데 다른 작업에 영향 많이 끼쳤다.

테스트 시 반복 작업, 비효율적

  • 패킷 작성 코드를 다른 타입의 메시지마다 작성, 삭제 반복
  • 해결 방법
    • 더미 클라이언트를 새 프로젝트로 분리해서 통신에 관한 코드를 작성하고 새 메시지를 테스트 할 때 빠르게 작업할 수 있게 하였다.
  • 느낀 점
    • 채용 공고를 보면 개발 툴이나 테스트 코드를 위한 개발자를 뽑는데 이번에 그 필요성을 느꼈다. 효율적인 테스트 방법도 염두에 둬야할 것이다.

사전 시스템 파악 미흡으로 인한 작업 시간 증대

  • 사양을 제대로 파악하지 못해 설계가 올바르지 못했고, 이에 따라 뒤늦게 기존 코드 고쳐야했다.
  • 느낀 점
    • 게임 서버가 무엇인가. 이 고민을 깊게 하지 않았다. 결과물의 형태는 그저 클라이언트의 패킷을 다른 클라이언트에게 보낼 뿐인 중계기의 형태를 띄었다.
    • 알지 못하는 분야인 게임 서버를 처음부터 만들다 보니 무엇을 만들어야 하고 필요할지, 어떻게 만들지. 코드는 어떻게 수정, 확장될 수 있을지, 기능이 어떻게 쓰여야 하는지, 잘못된 부분은 없는지, 외부의 접근은 어디까지 허용할지 등 수많은 고민이 필요했다.
    • 구현을 시작하기 전에 보다 체계적이고 구체적으로 설계하고 개발 중에 이를 검증하고 계획을 조정하는 과정이 필요했다.

락을 사용시 생긴 문제의 원인을 찾는 것에 많은 시간 소모

  • 하나의 클래스가 하나의 책임을 가지지 않아 User에 여러 클래스(Room , PacketHandler, Game, GameSession)가 접근했고 데드락과 포인터 관련 문제가 많이 생겼다.
  • 해결 방법
    • 디버그, 예외처리문을 활용해서 원인을 찾은 뒤 ,리팩토링을 했다.
      • User의 관리는 Game만 하게 했다.
      • PacketHandler는 패킷 처리를 할 때 Game 클래스와 인터페이스를 통해서 User에 접근했다.
      • Session은 User를 직접 다루는 대신에 UserID를 갖고 필요한 작업을 PakcetHandler를 통해 요청했다.
      • Room은 클라이언트의 입장과 퇴장, 브로드캐스팅만 전담하게 하였다.
  • 느낀 점
    • 단일 책임 원칙의 중요성과 멀티 스레드 환경의 위험성을 다시금 깨달았다. 책임을 명확히 함으로 앞서 명시한 많은 문제가 해결되었다.

게임이 종료 후 락이 풀리면서 (이동, 공격) 함수의 작업이 진행되어 nullptr이 되었는데 참조해서 오류 발생

  • 해결 방법
    • isEnd 변수를 만들어 게임이 끝나면 함수가 진행되지 않고 return
    • this==nullptr 로 확인하여 함수 작업
    • C++ 사용 중 메모리 관리의 위험성과 난이도를 직접 경험했다.
  • 느낀 점
    • 메모리 이슈로 Rust에 관심이 생겼고, 캠프 이후 공부를 시작할 계획이다. C++과 Rust의 메모리 관리를 모두 이해하면 시너지 효과가 있을 것 같다.

팀원의 문제를 제대로 파악하지 못해서 쉽게 해결할 수 있는 것에 시간이 많이 쓰였다.

  • 공간과 시간적 제약 때문에 6시면 스터디 카페를 나가야 했고, 엘리베이터에서 나누는 대화는 충분하지 않았다. (곡해와 오해)
  • 느낀 점
    • 이슈가 생겼을 때 문서로 전달하는 것의 필요성을 느꼈고 다음 프로젝트에서 이슈를 문서로 정리할 때 좋은 방법들을 찾아볼 것이다.
profile
rust로 뭐할까

0개의 댓글