Hi there. I have problem with strawberry + django + asgi
repo to reproduce https://github.com/Arfey/strawberry_django_sync_to_async_deadlock
anyio==3.7.0
asgiref==3.6.0
click==8.1.3
Django==4.1.9
graphql-core==3.2.3
gunicorn==20.1.0
h11==0.14.0
idna==3.4
python-dateutil==2.8.2
python-multipart==0.0.6
six==1.16.0
sniffio==1.3.0
sqlparse==0.4.4
starlette==0.27.0
strawberry-graphql==0.178.0
typing_extensions==4.6.2
uvicorn==0.22.0
all is fine when we use async code
@strawberry.type
class Query:
@strawberry.field
async def without_deadlock(self, info: Info) -> str:
return 'without_deadlock'
{
withoutDeadlock
}
but when we use sync_to_async we have a problem
@strawberry.type
class Query:
@strawberry.field
async def with_deadlock(self, info: Info) -> str:
return await sync_to_async(lambda: 'with_deadlock', thread_sensitive=True)()
{
withDeadlock
}
when we use thread_sensitive=False
we don't have any problem. When we use it in simple view we don't have any problem with sync_to_async
async def view(request: HttpRequest) -> HttpResponse:
await sync_to_async(lambda: None, thread_sensitive=True)()
await sync_to_async(lambda: None, thread_sensitive=False)()
return HttpResponse('ok')
to reproduce this bug we need to add any sync middleware to django settings.
def sync_middleware(get_response):
def middleware(request):
return get_response(request)
return middleware
MIDDLEWARE = [
...
# custom sync middleware
'app.middlewares.sync_middleware',
]
only after that we will see deadlock (but only for strawberry
view and sync_to_async
inside).
After conducting some research, I have identified that the issue is related to the async_to_sync
function used in the load_middleware
method. This function is used to wrap our async middleware and pass it as an argument to our sync middleware. However, it seems that there is a deadlock issue associated with the CurrentThreadExecutor
created by async_to_sync
.
I can't reproduce it for pure django views only for strawberry view. line with a deadlock
ExecutionContext.execute_field.<locals>.await_result()
any ideas why this is happening?
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too