FastAPI 와 코루틴
·
python
FastAPI Internal: Coroutine, Task, and the Event LoopFastAPI가 높은 성능을 내는 원리인 비동기 런타임(Asynchronous Runtime)의 핵심, async def의 작동 원리를 분석합니다. 이 원리를 이해하면 Hanging(요청 지연) 현상의 원인을 정확히 짚어내고, 불필요한 메모리 누수를 막을 수 있습니다.엔지니어라면 단순히 문법을 사용하는 것을 넘어, 코루틴이 메모리 상에서 어떻게 관리되고 스케줄링되는지 이해해야 합니다.🔑 이 글을 통해 얻어가는 것 3가지Hanging의 원인 규명: 왜 def 하나가 서버 전체를 멈추게 하는지 구조적으로 이해합니다.메모리 구조 시각화: 스택(Stack)과 힙(Heap)의 차이를 통해 코루틴의 상태 보존 원리를 파..
Fast API 사용법과 비동기
·
python
"FastAPI는 빠르다."이 명제는 반은 맞고 반은 틀렸습니다. FastAPI 자체가 마법을 부리는 것이 아니라, Python의 비동기 생태계(Asynchronous Ecosystem) 가 전통적인 동기 서버의 한계를 극복했기 때문입니다.도대체 Gunicorn(WSGI)으로는 왜 부족했는지, 그리고 현대적인 Python 서버 아키텍처는 C10K(1만 동시 접속) 문제를 어떻게 공학적으로 해결했는지, 그 심층부를 해부해 보겠습니다.1. 근본 원인 분석: 왜 동기(Sync) 서버는 멈추는가?전통적인 웹 프레임워크(Flask, Django)가 사용하는 동기 I/O 모델의 가장 큰 병목은 Context Switching 비용과 리소스 유휴 상태(Idle) 입니다.1.1 OS 스레드 모델의 한계동기 서버는 '요..
TypeError: must be str or None, not ModelPrivateAttr
·
트러블슈팅
"내부 변수니까 _variable로 선언해야지" 하고 코드를 작성했다가, 예상치 못한 TypeError를 마주친 적 있으신가요?특히 Pydantic v2를 사용하면서 Class 내부 상수를 정의할 때 이 문제를 자주 겪게 됩니다.이번 글에서는 TypeError: must be str, not ModelPrivateAttr 에러가 발생하는 기술적 원인을 분석하고, Pydantic의 설계 의도에 부합하는 ClassVar 패턴을 소개합니다.1. 문제 상황: "분명 문자열을 넣었는데?"다음과 같이 복합 ID를 파싱하는 Pydantic 모델을 만들었다고 가정해 봅시다. 내부에서만 쓸 구분자(_delim)를 정의하고, split 함수에 넘겨주었습니다.from pydantic import BaseModelclass ..
MySQL vs PostgreSQL
·
DB
[Deep Dive] MySQL vs PostgreSQL: 인덱스 아키텍처와 성능의 비밀같은 RDBMS라도 MySQL(InnoDB)과 PostgreSQL은 데이터를 저장하고 관리하는 내부 아키텍처가 완전히 다릅니다. 이 구조적 차이는 읽기와 쓰기 성능, 그리고 쿼리 튜닝 전략에 결정적인 영향을 미칩니다.이 글에서는 두 데이터베이스의 핵심적인 차이인 Clustered Index(MySQL)와 Heap(PostgreSQL) 구조를 중심으로, 인덱스 동작 방식과 그에 따른 성능 특성을 깊이 있게 분석해 봅니다.1. 기본 구조의 차이: Clustered Index vs Heap가장 큰 차이점은 "데이터가 물리적으로 어떻게 저장되는가"에 있습니다.MySQL (InnoDB): Clustered IndexMySQL의..
FastAPI Event Loop Mismatch
·
트러블슈팅
[Python/AsyncIO] APScheduler와 SQLAlchemy 비동기 세션 충돌 (Event Loop Mismatch)APScheduler로 백그라운드 작업을 돌리다가 한 번쯤은 마주치게 되는 이벤트 루프 미스매치(Event Loop Mismatch).특히 FastAPI와 SQLAlchemy 비동기 세션을 함께 쓸 때 자주 발생하는 이 문제, 정확히 왜 발생하고 어떻게 해결해야 할까요?다음과 같은 에러 로그를 보셨다면, 오늘 이야기가 도움이 될 겁니다.RuntimeError: Task got Future attached to a different loop1. 문제 상황: 메인 스레드 vs 스케줄러 스레드보통 FastAPI 서버(uvicorn)가 뜨면 메인 스레드에 이벤트 루프(Loop A)..
Contextlib
·
python
sqlalchemy 를 사용하여 세션을 얻고 트랜잭션을 여는 흔한 코드는 다음과같다.from sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerfrom models import Userengine = create_engine("sqlite:///example.db", echo=True)SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)def find_by_id(user_id: int): session = SessionLocal() # 세션 얻기 try: session.begin() # 트랜잭션 시작 user = ..
FastAPI Depends
·
python
들어가기 앞서자바를 메인언어로 백엔드를 공부했지만 어쩔수없이 FastAPI 를 해야하니 알아보는 시간을 갖도록 했다.자바에서도 DB 와 같은 외부 서드파티 저장소와의 연결을 위한 Connection 객체가 있듯,Python 에서도 충분히 있을거라고 생각했고Springboot 때 처럼 커넥션 객체를 트랜잭션이 시작할때 열리고 트랜잭션 종료때 반환되는 방식인가 했지만?Depends 라는 녀석을 Springboot 로 따지만 Controller 함수에서 사용하는것 처럼 보인다. 필자가 사용하는 환경은 아래와 같다.Lang: Python 3.11ORM: sqlalchemy 2.0.23web: FastAPI 0.104.1사용from fastapi import FastAPI, Depends, HTTPExceptio..
Springboot에서 SpringSecurity는 어떻게 초기화되는가? - 중
·
Web-Spring
개요이전 포스팅에서 Springboot의 초기화 시작점에서 SpringSecurity의 세팅이 어떻게 이뤄지는지 보았다면,이번 포스팅에서는 SpringSecurity내에 기본 필터들이 어떻게 초기화과정을 거치는지 알 수 있어요. 흔히 `securityFilterChain` Bean을 설정하는 코드에서`addFilterBefore()` 이나 `addFilterAfter()` 등을 사용하여 커스텀 시큐리티 필터를 등록하곤 해요이 메소드들의 동작도 함께 알아봅시다. 사전지식이전 포스팅의 사전지식과 동일하며, 해당 포스팅의 글을 읽고 오면 더욱 좋습니다.이전 포스팅을 읽은 적이 없다면, SecurityArchitecture을 이해하고 오면 좋습니다. 저번 포스팅에서 넘어오자면...저번 포스팅의 마지막에서 `We..