3주차 수요일 그룹 4 - woowa-techcamp-2024/dev-log GitHub Wiki

그룹 리뷰 (24-07-10)

  • 참여인원: 이호석, 김현우, 이경민, 박민지, 유동근

이호석

호석's WAS 흐름

  1. 사용자 요청 Multi Thread 분기

    • ThreadPoolExecutor를 통해 쓰레드 풀을 만들고 각 요청에 대해 스레드 풀의 스레드로 연결합니다.
    • 이후 각 요청마다 HttpRequest, HttpResponse 객체가 만들어지고 요청을 독립적으로 처리할 수 있도록 합니다.
  2. ConnectionHandler가 요청에 따른 RequestHandler를 찾는다.

    • ConnectionHandler는 현재 HttpRequest를 처리할 수 있는 핸들러를 요청 경로를 통해 RequestHandler를 찾습니다.
  3. RequestHandler의 요청 처리

    • RequestHandler에게 HttpRequest, HttpResponse를 넘겨주면서 처리를 요청합니다.
    • RequestHandler는 비즈니스 로직을 처리합니다.
    • RequestHandler는 HttpResponse에게 redirect 혹은 forward 처리를 요청합니다.
    • HttpResponse는 브라우저에게 응답을 반환하여 하나의 사용자 요청이 마무리 됩니다.

질문 받은것

  • Optional을 왜 쓰지 않고 null을 직접 반환할까?
    • WAS 레벨에서 사용자가 어떤 값을 원하는지 모르는데 임의의 값을 반환하는게 괜찮을까란 고민이 있었습니다.

구현하면서 고민했던 부분

  • 미션을 진행할때 변경되는 부분을 어떤 객체의 책임으로 넣어야 하는지 고민이 있었습니다.
  • 그리고 구현할때 어디까지 고려하는지,, 이런 부분이 많이 어려웠워요 ㅠㅠ

인사이트를 얻은 부분

  • 템플릿 엔진을 손수구현하는 부분이 정말 대단하다,, 라는 생각이 들었어요
  • 필터를 통한 공통 로직 추상화도 정말 도입해볼만 하다! 라는 생각이 들었습니다~
  • 다들 자신만의 관점이나 기준을 가지고 진행하는데, 저도 제 자신의 관점을 잘 가져가야겠습니다~

김현우

CleanShot 2024-07-10 at 21 32 04

나의 구현

  • 서버가 요청을 준다.
  • 요청으로 부터 Request객체를 만든다. 또한, 빈 Response객체를 만든다.
  • FilterChain에서 순차적으로 Filter를 거치면서 요청을 처리한다.
  • 이후 Filter를 거치고 Filter를 모두 소진하면 Handler Mapper로 넘어간다.
  • 요청에 Handler를 가져오고 맞는 Handler에서 요청을 처리한다.
  • ResponseValueWriter에서 응답 내용을 서술한다.

느낀점

  • 내 구현은 정말 필요한 구현만 하는 것을 목표로 두었다. 복잡한 기능보다는 간결한 구조에서 나오는 유지보수성을 우선으로 생각했다.
  • 이렇게 코딩을 하니 남들에 비해서 마치는 시간은 빠르지만, 남들이 어떻게 기능을 심화시켰는지, 다른 생각은 어떻게 하는지를 보는 맛도 있었다.
  • 또한, 남들의 코드를 보면서 Optional을 적극 활용했어야 겠다고 후회하는 중입니다. (Session 처리 관련해서 얘를 먹었습니다.)

이경민

⚙️ 프로젝트 동작 방식

  • Main 클래스에서 원하는 포트를 갖는 ServerSocket을 생성합니다.
  • ServerSocket이 생성되면서 구현된 모든 EndPointHandler를 핸들링해 EndPoint를 생성 및 저장합니다.
    • 예시 이미지에서는 8080 포트를 사용합니다.
  • HTTP 요청이 들어오면 ServerSocket은 요청에 대한 ConnectionRunner를 스레드로 실행합니다.
    • ConnectionRunner는 HTTP 요청 InputStreamHttpRequestHandler에 위임합니다.
    • HttpRequestHandlerInputStream을 파싱해 HttpRequest 객체를 생성합니다.
    • 파싱한 HttpRequest 객체를 기반으로 EndPoint를 찾아 HttpResponse를 생성 및 ConnectionRunner에게 반환합니다.
  • ConnectionRunnerHttpResponseOutputStream에 쓰고, Socket을 닫습니다.

❓ 고민과 구현해야할 것들

  • Session 구현 방식을 어떻게 적용해야 할지 고민하고 있습니다.
    • 현우님의 ThreadLocal 방식을 참고해서 SecurityContext 와 유사한 방식으로 구현해볼까 합니다.
  • Login 로직이 너무 복잡해서 어떻게 처리해야할까요..
    • 동근님의 Filter 로직을 참고해서 리팩토링을 해야할 것 같습니다.
  • 정적 페이지 생성을 어떻게 접근해야할지 아직 고민이 많습니다... ㅠㅠ 어려운 것 같습니다!

☕️ 소감

  • 내 코드가 초라해보이는(?) 효과를 얻었습니다.. ㅠㅠ
  • 다른 사람의 아이디어에 기반해 리팩토링 아이디어를 얻는 점은 매우 좋은 것 같습니다!
  • 탬플릿엔진은 구현하기 어려울거같아서... 지켜만 보겠습니다 :D

박민지

[구현 내용]

  • 소켓에서 문자열 리더, 이미지 리더 등 다형성을 고려하여 소켓 계층을 한 번 더 추상화하였습니다.
  • Session과 SessionManager를 정의하고, timeout을 고려하기 위해 Session에 접근할 때마다 만료 여부를 검사하고, SessionManager에서 SessionPool 크기가 다 차면, 만료된 세션을 삭제하는 로직을 구현하였습니다.
    • 관련 동시성 이슈가 있을 수 있어 확인할 예정입니다.
  • 헤더에 쿠키를 설정하는 로직은 쿠키 객체를 만들어 책임을 분리할 예정입니다.
  • 세션 매니저를 정의하여 의존성 관리가 점점 힘들어져서 컨테이너를 고려하고 구현하였습니다.

[배운 점]

  • ThreadLocal을 사용하여 요청을 처리할 때 필요한 모든 정보에 대해 접근 가능하도록 구현할 수 있다는 점을 배웠습니다.
  • 간단한 템플릿 엔진을 구현하신 분이 계셨는데, 실제로 템플릿 엔진이 어떻게 구현되었겠구나, 배울 수 있었습니다.
  • 각 책임에 따라 객체로 분리해서, 책임이 많이 분리되어 간단해진 코드를 봤는데, 의도를 잘 드러내는 방법이겠구나, 라는 생각이 들었습니다.

[후기]

  • 다들 저보다 더 많이 구현하셔서 동기 부여가 되었습니다!
  • 생각보다 리팩토링할 부분이 많이 보여서 오늘 열심히 해야 할 것 같습니다!
  • 6단계가 생각보다 어렵겠구나, 싶습니다. 더 파이팅!!!
  • filter 비스무리한 로직이 필요하겠구나, 싶습니다. 구조가 다양해서 좋았습니다!!!

유동근

고민한 점

  • 동적으로 html을 편집하는 방법을 많이 고민하게 되었습니다. 특수한 속성을 가진 html element의 정보를 동적으로 조작하는 방식을 고민했고 자바스크립트 돔 구조와 유사한 객체를 생성해서 조작하는 방식을 생각했습니다.

인상적인 부분

  • ThreadLocal : thread의 생명주기와 동일한 객체를 관리하는 요구사항을 적용하기에 적합한 방식이라는 생각이 들었습니다. ThreadLocal에 대해서 생각하지 못했는데 이것을 사용한 코드를 볼 수 있어서 좋았습니다.
  • Optional : 동적 html 구현을 하면서 nullable 한 리턴 타입을 사용하는 일이 많았아서 null로 인한 에러가 많이 발생했습니다. Optional을 적용하여 명시적으로 분기처리를 하면 버그를 줄일 수 있을 것이라는 생각이 들어서 인상깊었던 부분이었습니다.