20220112

Django 4 async view 실제 사용 후기

Django 4.0 나오고 async view를 사이드 프로젝트에 실제로 굴려본 후기. 3.0에서 문 열고 3.1/3.2 거치면서 ORM async까지 오긴 했는데 쓸만한 상태가 된 건 4.0부터라고 본다.

무엇이 되는가

  • async view / class-based async view
  • async middleware
  • QuerySet의 일부 async 메서드: aget(), acreate(), aupdate(), alen(), afirst(), async for로 iterate

쓴 코드

from django.http import JsonResponse
from .models import Order

async def order_detail(request, order_id):
    try:
        order = await Order.objects.aget(pk=order_id)
    except Order.DoesNotExist:
        return JsonResponse({"error": "not found"}, status=404)
    items = [i async for i in order.items.all()]
    return JsonResponse({
        "id": order.pk,
        "status": order.status,
        "items": [{"sku": x.sku, "qty": x.qty} for x in items],
    })

걸리는 한계

  1. prefetch_related, select_related는 여전히 sync. async context 안에서 쓰려면 sync_to_async로 감싸야 함. 깊은 관계 조회가 많은 API는 결국 반쪽.
  2. Manager 메서드 커스텀한 것들은 async 대응 별도. 팀 내 custom manager 많으면 귀찮다.
  3. ASGI 서버 필수. uvicorn or daphne. 기존 gunicorn wsgi 쓰던 파이프라인 손봐야 함.
  4. middleware 체인에서 sync/async 섞이면 async adapter가 자동 삽입되지만 성능 이득이 깎임. 일관성 유지 필요.

체감

외부 HTTP 호출 섞인 엔드포인트에서 동시성 이득 확실. 순수 DB 조회만 하는 엔드포인트는 async 한다고 빨라지지 않는다(어차피 postgres 드라이버 블로킹인 시간은 그대로). "async view 안에서 httpx async client로 외부 콜 여러 개 gather"가 진짜 이득 볼 때.

결론

"전체를 async로 가자"라고 전환하면 후회한다. 외부 호출이 몰린 엔드포인트만 선택적으로. FastAPI만큼 급진적으로 async 하고 싶으면 FastAPI가 맞음. Django가 장기적으로 가는 길에 올라탄 것.

댓글 없음: