teamhide / blog-comments

hides.tistory.com comments repo
0 stars 0 forks source link

1077 #4

Open utterances-bot opened 2 years ago

utterances-bot commented 2 years ago

Hide :: FastAPI SQLAlchemy Session 객체 연동하기

개요 동기적으로 돌아가는 서버의 경우 Thread-local을 적용하면 각 Request별로 다른 Context를 가지도록 할 수 있다. 하지만 asyncio를 통해 이벤트 루프를 사용하는 비동기 서버의 경우(FastAPI, Sanic...) Thr..

https://www.hides.kr/1077

Taekhyang commented 2 years ago

덕분에 참고 많이 하면서 공부하고있습니다 ㅎㅎ 제가 여쭤보고싶은것들이 몇가지 있는데 답변해주시면 정말 감사드리겠습니다!

  1. sqlalchemy 의 디폴트 내부구현체인 threading.local() 을 scopefunc 로 안쓰는 이유가, threading.local() 은 스레드 별로 scope 가 관리되는거고 (멀티스레딩 환경) fastapi 는 싱글스레드에서 여러 요청을 처리하기때문에, 싱글스레드에서도 context(request) 별로 scope 를 나눌 수 있는 contextvar 를 통해 관리가 되는건가요?
  2. session.execute() 를 할 때 비로소 contextvar 에 set 해놓은 uuid 가 현재 세션과 매핑이 되는 것인가요? 미들웨어 이후에 session.execute() 부분이 처음 등장하는 부분이라서 이곳에서 최초로 request uuid 와 session 이 매핑되는거겠죠..?
  3. 마지막에 reset_session_context(context=context) 이 없으면 어떤 문제가 생기는지 궁금합니다.
teamhide commented 2 years ago

@Taekhyang 안녕하세요 :)

  1. 기본적으로 Thread-local과 Context-local의 차이점에 대해 이해하시면 좋습니다. 말씀하신 것 처럼 FastAPI같은 비동기 프레임워크의 경우 코루틴을 활용하여 비동기 처리를 진행하는데요. 코루틴은 하나의 스레드에서 제어권을 주고 받으며 동작하기 때문에 Thread-local을 적용할 필요가 없습니다. 동일한 스레드이니까요ㅎㅎ 따라서 contextvar를 통해 동일한 스레드이지만 각 작업별로 다른 컨텍스트를 가져갈 수 있도록 해야합니다.

  2. 미들웨어에서 현재의 컨텍스트에 맞게 세션객체를 구성합니다. https://github.com/teamhide/fastapi-boilerplate/blob/master/core/fastapi/middlewares/sqlalchemy.py 를 보시면 미들웨어가 구현되어있구요. https://github.com/teamhide/fastapi-boilerplate/blob/master/app/server.py#L62 를 보시면 해당 미들웨어를 등록하는걸 확인할 수 있습니다.

  3. 이 부분은 GC가 어떻게 동작하는지 파악해야하는데요. Request cycle이 종료될 때 자동으로 사용하지않는 객체를 수거해간다고 생각하고는 있지만, 좀 더 확실하게 사용한 컨텍스트를 반납해주기 위해 명시적으로 사용해주고 있습니다.

https://www.hides.kr/1103 여기에 FastAPI와 SQLAlchemy에 대해서 최종적으로 정리한 글이 있는데 한번 참고해보시면 좋을 것 같네요. 추가 질문 있으면 편하게 댓글 달아주세요~

Taekhyang commented 2 years ago

@teamhide 답변 감사합니다 !! 마지막 링크가 전반적인 이해에 도움이 많이 되었습니다 ㅎㅎ