Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#33795 closed Bug (needsinfo)

Django sync_to_async takes infinite time with asgiref 3.5.1+

Reported by: parfeniukink Owned by: nobody
Component: HTTP handling Version: 3.2
Severity: Normal Keywords: asgiref sync_to_async
Cc: Andrew Godwin, Carlton Gibson Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by parfeniukink)

Django==3.2.13
asgiref==3.5.2

If you will try to decorate any ORM function with sync_to_async you will wait forever.

asgiref==3.5.0 works fine

# models.py
class DTOManager(models.Manager):
    @sync_to_async
    def filter(self, *args, **kwargs) -> list[BaseModel]:
        return [self._dto_mapper(i) for i in self.model.objects.filter(*args, **kwargs)]

    @sync_to_async
    def get(self, *args, **kwargs) -> BaseModel:
        try:
            return self._dto_mapper(self.model.objects.get(*args, **kwargs))
        except self.model.DoesNotExist:
            raise ObjectNotFound(f"{self.model.__name__} not found")

class Hotel(models.Model):
    id = models.UUIDField(primary_key=True, editable=False)
    coordinates = models.PointField(null=True)

    dto_objects = DTOManager(dto_mapper=lambda hotel: HotelDTO(**hotel.curated_data) if hotel else None)
    objects = models.Manager()

# services.py
hotels = await Hotel.dto_objects.filter(id=12)

Change History (4)

comment:1 by parfeniukink, 2 years ago

Description: modified (diff)

comment:2 by Mariusz Felisiak, 2 years ago

Cc: Andrew Godwin Carlton Gibson added
Component: UncategorizedHTTP handling
Summary: Django sync_to_async takes infinite time with asgiref==3.5.2Django sync_to_async takes infinite time with asgiref 3.5.1+

Maybe it's not related but I noticed that test_request_lifecycle_signals_dispatched_with_thread_sensitive crashes on the stable/3.2.x branch with asgiref 3.5.1+:

======================================================================
ERROR: test_request_lifecycle_signals_dispatched_with_thread_sensitive (asgi.tests.ASGITest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/django/tests/asgi/tests.py", line 240, in test_request_lifecycle_signals_dispatched_with_thread_sensitive
    target_thread = next(iter(SyncToAsync.single_thread_executor._threads))
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.8/unittest/case.py", line 60, in testPartExecutor
    yield
  File "/usr/lib/python3.8/unittest/case.py", line 676, in run
    self._callTestMethod(testMethod)
  File "/usr/lib/python3.8/unittest/case.py", line 633, in _callTestMethod
    method()
  File "/.virtualenvs/django-test-3.8/lib/python3.8/site-packages/asgiref/sync.py", line 213, in __call__
    return call_result.result()
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 437, in result
    return self.__get_result()
  File "/usr/lib/python3.8/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/.virtualenvs/django-test-3.8/lib/python3.8/site-packages/asgiref/sync.py", line 279, in main_wrap
    result = await self.awaitable(*args, **kwargs)
RuntimeError: coroutine raised StopIteration

As far as I'm aware these issues are caused by asgiref/add57649, however we will not backport 36fa071d6ebd18a61c4d7f1b5c9d17106134bd44 so I would restrict supported version:

  • setup.cfg

    diff --git a/setup.cfg b/setup.cfg
    index 0f96cf325d..2b6f9b82ef 100644
    a b scripts = django/bin/django-admin.py  
    4242include_package_data = true
    4343zip_safe = false
    4444install_requires =
    45     asgiref >= 3.3.2, < 4
     45    asgiref >= 3.3.2, < 3.5.1
    4646    pytz
    4747    sqlparse >= 0.2.2
    4848
Last edited 2 years ago by Mariusz Felisiak (previous) (diff)

comment:3 by Mariusz Felisiak, 2 years ago

Resolution: needsinfo
Status: newclosed

Also, it works for me with Django 3.2.13, asgiref 3.5.2 and Python 3.8.10 🤔.

in reply to:  2 comment:4 by Mariusz Felisiak, 2 years ago

Replying to Mariusz Felisiak:

Maybe it's not related but I noticed that test_request_lifecycle_signals_dispatched_with_thread_sensitive crashes on the stable/3.2.x branch with asgiref 3.5.1+

Potential fix: PR.

Note: See TracTickets for help on using tickets.
Back to Top