1

I am running an async django application that is downloading some data. As I want the downloads to run asynchronously, I defined some async methods to run as coroutines. These methods sometimes have Django ORM queries, which I also run asynchronously (async for loop, sync_to_async or .aget(), for example). Since I'd like to display the download progress in clients browser in realtime, I installed django-channels together with daphne to setup websockets. However, If I run my code without daphne, everything works perfect. But as soon as I register daphne as app in settings.py (that runserver is actually running daphne serevr), the code stucks at a async database query.

More details:

settings.py:

ASGI_APPLICATION = 'MultiClaw.asgi.application'
INSTALLED_APPS = [
 'daphne',
 ...
]

The view, that is mapped to a button which starts the download:

@csrf_exempt
def start_grab_thread(request):
 parser_name = request.POST['parser_name']
 settings_model = Settings.objects.filter(user=request.user, parser_name=parser_name)[0]
 parser_module = importlib.import_module(f'parser.Parser.{parser_name}')
 parser_class = getattr(parser_module, parser_name)
 parser_instance: Core = parser_class(settings_model)
 
 asyncio.run(parser_instance.download_products())
 
 if request.method == "POST": 
 return redirect('start')

the function, where the problem occures:

async def download_products(self):
 
 print('downloading products')
 
 collected_product_urls = self.product_url_list
 print(f'{collected_product_urls=}')
 
 product_urls_from_db = set([
 product.source_url async for product in 
 Product.objects
 .filter(pk__in=collected_product_urls)
 ])
 
 print(f'{product_urls_from_db=}')
 print(f'FINALLY GOT IT') 
 return

I tried many attempts, wrap the query into a function, decorate it with database_sync_to_async, async_to_sync...

I also have defined a test function with asyncio.sleep(1), to test if await generally does not work.

But I realized, that only async database queries do not work.

The code just stops. It seems that something is blocking the database query execution. I have no errors, I just cannot see what happens that it just stucks there forever and I can never see this 'FINALLY GOT IT' output when daphne server is running.

I hope you can help me to fix that, thanks a lot!

UPDATE: After 2 days of intensive research I finally managed to fix it by myself with some simple changes:

changed the view to async, details:

from:

@csrf_exempt
def start_grab_thread(request):
 parser_name = request.POST['parser_name']
 settings_model = Settings.objects.filter(user=request.user, parser_name=parser_name)[0]
 parser_module = importlib.import_module(f'parser.Parser.{parser_name}')
 parser_class = getattr(parser_module, parser_name)
 parser_instance: Core = parser_class(settings_model)
 
 asyncio.run(parser_instance.download_products())
 
 if request.method == "POST": 
 return redirect('start')

to:

@csrf_exempt
async def start_grab_thread(request):
 parser_name = request.POST['parser_name']
 settings_model = await Settings.objects.aget(user=request.user, parser_name=parser_name)
 parser_module = importlib.import_module(f'parser.Parser.{parser_name}')
 parser_class = getattr(parser_module, parser_name)
 parser_instance: Core = parser_class(settings_model)
 
 await parser_instance.download_products()
 
 if request.method == "POST": 
 return redirect('start')
asked Jun 26, 2024 at 1:03
2
  • I don't see anything blatantly incorrect. Does it work when you implement the same method in a sync fashion? Commented Jun 26, 2024 at 4:58
  • Yes, just checked it. More Details: Changed async def to def, and commented out some async code to test the database query and it works. The matter is, that this approach does not solve the overall problem with not being able to async query some database data... Commented Jun 26, 2024 at 8:47

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.