반응형

uvicorn을 통해 websocket을 테스트 하던 중 처음 보는 오류를 발견했다.

찾아보니 app registry가 준비되기 전에 특정 라이브러리가 import 되어 발생하는 오류였고, 처음 import 한 부분을 찾아가니 나의 경우는 처음에 asgi.py를 잘못 작성해서 생긴 문제였다.

 

오류가 생긴 asgi.py 코드는

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from accounts import routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')

application = ProtocolTypeRouter({
    "http": get_asgi_application(),
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routing.websocket_urlpatterns
        )
    ),
})

로 django_asgi_app = get_asgi_application() 부분이 routing이 auth 보다 뒤에 나오는 상황이었다.

 

 

오류 코드를 자세히 찾아보니 routing 부분에서 consumer를 불러오고 consumer에서 rest_framework_simplejwt.tokens을 불러오는 부분에서 문제가 발생했고, app registry가 준비되기 전 해당 부분을 불러와서 발생한 오류임을 확인했다.

 

즉, get_asgi_application으로 app registry가 준비되기 전, routing에서 사용된 라이브러리 중 rest_framework_simplejwt.tokens.AccessToken이 먼저 불러와져 발생하는 오류였다.

 

 

간단하게 아래와 같이 코드 순서를 바꿔주어 오류를 수정하였다.

import os

from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
django_asgi_app = get_asgi_application()

from channels.auth import AuthMiddlewareStack
from accounts import routing

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": AuthMiddlewareStack(
        URLRouter(
            routing.websocket_urlpatterns
        )
    ),
})

 

결과적으로 잘 작동하는 것을 확인했다.

반응형

'BackEnd > django' 카테고리의 다른 글

[django] LocMemCache 배포 시 문제점  (0) 2024.09.01
반응형

오류 확인 배경

 django를 배포하고 프런트와 합치면서 테스트하는 과정에서 신기한 현상을 발견했다. 임시로 접속할 수 있는 페이지를 만들기 위해 local memory cache를 사용해 권한을 확인하고 있었고 해당 페이지 테스트하고 있었다.  

 

 그런데 페이지를 새로고침 할 때마다 인증이 잘 될 때도 있고 안 될 때도 있는 것이다. 정확히는 서버 cache에 쿠키의 cache가 없어서 권한이 없다는 경우와 정상적으로 있어서 잘 동작하는 경우, 이 두 경우가 새로고침 할 때마다 랜덤으로 반복되었다. 보통 동작이 되면 되고 아니면 아닌데 어떻게 새로고침할 때마다 랜덤으로 오류가 발생하는일이 벌어지는 걸까?

 

왜 이런 일이 벌어진 걸까?

 LocMemCache는 django를 동작하는 프로세스의 메모리에만 접근이 가능하다. 따라서 하나의 프로세스에선 문제가 없고 당연히 테스트 환경에서도 문제가 없다.

 

 하지만 우리가 배포하는 환경은 다르다. 보통 django를 배포할 때 gunicorn으로 worker를 1이상으로 세팅하여 배포하게 된다, 이러면 worker마다 mem이 다르기 때문에 cache가 있는 worker에서만 정상 작동하게 되는 문제가 발생한다.

 

마치 슈뢰딩거의 cache 랄까?

 

따라서 LocMemCache를 쓰지 말고 db cache를 사용하도록 하자. 

 

db cache로 변경하기

 먼저 cache 세팅을 변경해준다

# settings.py
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
    }
}

 

 그 다음 terminal에서 캐시 db 테이블을 생성해준다.

python manage.py createcachetable

 

반응형

+ Recent posts