목록으로
Django의 View에 비동기
Django에서 동기식과 비동기식 동작을 설명해보겠습니다. 우리가 매일 사용하는 웹 페이지는 많은 정보를 데이터베이스에서 가져와 보여줘요. Django는 이런 작업을 동기식과 비동기식 방식으로 처리할 수 있어요.
동기식 방식이란?
예를 들어, 동기식 방식은 마치 레스토랑에서 주문을 하고 음식이 나올 때까지 기다리는 것과 같아요. 주문을 하면 주방에서 음식을 만들기 시작하고, 음식이 나올 때까지 다른 일을 할 수 없죠. Django에서도 데이터베이스에서 정보를 가져올 때 이와 비슷하게 작동해요. 정보를 모두 가져올 때까지 기다려야 다음 단계로 넘어갈 수 있습니다.
비동기식 방식이란?
반면에 비동기식 방식은 주문을 하고 음식이 준비되는 동안 다른 일을 할 수 있는 것과 비슷해요. 예를 들어, 카페에서 커피를 주문하고 기다리는 동안 책을 읽을 수 있죠. Django에서도 이와 같이 데이터베이스에서 정보를 가져오는 동안 다른 작업을 동시에 처리할 수 있습니다.
Django에서 비동기식으로 전환하기
Django에서 비동기식으로 전환하면 성능이 크게 향상되기도 해요. 예를 들어, 아래와 같은 코드가 있습니다:
이 코드는 사용자의 프로필 정보를 보여주는데, user.something_set.complex_all()과 user.something_set.slow_all() 동작에서 시간이 좀 걸려요. 분석을 해보니 다행히 이 부분을 비동기식으로 바꾸면 성능이 향상된다는 걸 파악했습니다. 그래서 이 부분을 비동기식으로 바꿔 성능을 개선해보겠습니다.
여기선 async 키워드와 비동기 반복을 사용해서, 느린 데이터베이스 작업을 빠르게 처리하려고 합니다. 비동기식으로 바꾸면 여러 작업을 동시에 처리할 수 있어, 결과적으로 페이지가 더 빨리 로드됩니다.
그런데 여기서 문제가 하나 생겨요. Django의 일부 부분은 여전히 동기식으로 작동하다 보니, SynchronousOnlyOperation 같은 오류가 발생할 수 있어요. Django 내부 동작이 전부 비동기식으로 작동하는 게 아니거든요. 이건 마치 자동차가 동시에 가솔린과 전기로 움직이려 하다가 헷갈리는 것과 비슷한 상황이죠.
이 문제를 해결하기 위해 asgiref.sync 모듈에 있는 sync_to_async 함수를 사용할 수 있어요. 비동기식으로 수행되는 상황에서 동기식으로 동작하는 부분을 비동기식으로 동작하도록 감싸주는 함수지요.
두 가지 방식을 각각 사용해봤습니다. 먼저 render() 함수는 동기식으로 동작하는 함수이므로 이 함수를 sync_to_async 함수로 감싸서 비동기식으로 동작하는 코루틴으로 변환했어요.
request.user는 함수나 메서드가 아니므로 sync_to_async(request.user) 형식으로 감쌀 수 없어요. 그래서 request.user 를 그대로 반환하는 익명 함수를 lambda 예약어로 즉석에서 생성해서 sync_to_async 함수로 감쌌지요.
이렇게 하면 동기식으로 작동하는 부분을 비동기식으로 '감싸서' 문제를 해결할 수 있습니다. 생각보다 간단하죠? 하지만, 다른 도구들과 함께 사용할 때는 조금 더 복잡한 문제들이 생길 수 있어요. 예를 들어, 의존성 주입 도구를 사용하면 Django의 오류 화면이 제대로 표시되지 않는 경우가 있습니다. 이런 문제들은 Django에 비동기 기술이 아직 완전히 정착되지 않았기 때문에 발생하는 거예요.
그럼에도 Django에 비동기 기술을 사용하는 건, 상황에 따라서는 성능 향상이 두드러지기 때문이에요. 아직 Django에 비동기 동작을 구현하기 어려워보이기도 하고요. 하지만 걱정하지 마세요! 푸딩캠프 강의에서는 이런 내용을 더욱 쉽고 재미있게 설명해 드릴 거예요. 푸딩캠프와 함께라면 분명 더 빠르게 배울 수 있을 거라고 확신합니다.
푸딩캠프 뉴스레터를 구독하면 학습과 성장, 기술에 관해 요약된 컨텐츠를 매주 편하게 받아보실 수 있습니다.