Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django RuntimeError at /admin/users/user/1/change/, Single thread executor already being used, would deadlock

I tried to make a chat app with django-channels. But a RuntimeError occurs when I create a new django-chanels project and edit data in the admin site.

I'm not sure that I think the error occurred because I made several django-channels projects.

When I built my first project, WebSocket is not working, so I made another 2nd, 3rd, 4th project with django-channels. Now WebSocket is connected, but I have trouble with RuntimeError (Error message: Single thread executor already being user, would deadlock)

What can I do to fix this?

myproject/settings.py

import os
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-is!$&voe3y058!2sus9egmxh@d!$)=l&o8_vl=m8zz!ap+d#a#"

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "users.apps.UsersConfig",
    "channels",
    "core.apps.CoreConfig",
    "broadcasts.apps.BroadcastsConfig",
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "busker.urls"

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    },
]

WSGI_APPLICATION = "busker.wsgi.application"


# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": BASE_DIR / "db.sqlite3",
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = "/static/"

STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

ASGI_APPLICATION = "busker.asgi.application"

CHANNEL_LAYERS = {"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"}}

AUTH_USER_MODEL = "users.User"

myproject/asgi.py

import os

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

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

application = ProtocolTypeRouter(
    {
        "http": get_asgi_application(),
        # Just HTTP for now. (We can add other protocols later.)
        "websocket": AuthMiddlewareStack(
            URLRouter(broadcasts.routing.websocket_urlpatterns)
        ),
    }
)

myapp/consumers.py

import json
from channels.generic.websocket import AsyncWebsocketConsumer


class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_group_name = "Test-Room"

        await self.channel_layer.group_add(self.room_group_name, self.channel_name)

        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(self.room_group_name, self.channel_name)

        print("Disconnected!")

    async def receive(self, text_data):
        receive_dict = json.loads(text_data)
        message = receive_dict["message"]

        await self.channel_layer.group_send(
            self.room_group_name, {"type": "send.message", "message": message}
        )

    async def send_message(self, event):
        message = event["message"]

        await self.send(text_data=json.dumps({"message": message}))

myapp/routing.py

from django.urls import re_path

from . import consumers

websocket_urlpatterns = [
    re_path(r"", consumers.ChatConsumer.as_asgi()),
]
like image 408
Ingyu Yang Avatar asked Jul 01 '21 10:07

Ingyu Yang


1 Answers

Try pip install 'asgiref==3.3.4'.

I noticed a similar RuntimeError: Single thread executor already being used, would deadlock after upgrading from asgiref 3.3.4 to 3.4.1.

This appears to be due to a currently unresolved issue in channels 3.0.4 where concurrent requests on the Django development server are intermittently failing. See also Runtime Error Deadlock occurring randomly in Django.

In 3.4.0, asgiref introduced additional deadlock checks. That's a good thing, but may have exposed an underlying issue in channels. From the changelog:

* Calling sync_to_async directly from inside itself (which causes a deadlock
  when in the default, thread-sensitive mode) now has deadlock detection.

If you do need to install asgiref >= 3.4.1, a workaround in development is to use python manage.py runserver --noasgi. This also has the benefit of being a little faster to reload.

like image 135
Ben Sturmfels Avatar answered Nov 16 '22 05:11

Ben Sturmfels