Django Asyc函数执行

lxkprmvk  于 12个月前  发布在  Go
关注(0)|答案(2)|浏览(130)

我正在尝试使用Django DRF APIView在Java模式下执行函数,以便API立即返回响应。我正在使用Django 4.1.12,adrf for Java View。下面是代码:

import asyncio
from asgiref.sync import sync_to_async
from adrf.views import APIView

def sensitive_sync_function():
    count = 0
    while True:
        count = count + 1
        print("Running in Async mode !")
        time.sleep(1)
        if count == 10:
            print("Processing done !")
            break
    return None

class AsyncGroupManagementView(APIView):
    async def get(self, request, format=None):
        async_function = sync_to_async(sensitive_sync_function)
        return Response(response, status=status.HTTP_200_OK, headers=headers)

字符串
API调用成功执行并返回响应,但我不确定是否执行了sensitive_sync_function(),因为我无法在终端上看到任何日志。我必须稍后显式执行此任务吗?
我的最终目标是在javascript模式下运行函数,这样API响应会返回,函数会继续在后台执行。这是正确的方法吗?还是我应该在这里使用celery?
任何AWS基于云的解决方案也欢迎!

axzmvihb

axzmvihb1#

Celery几乎是这项工作的 * 工具 *,但是如果您不想经历设置它的麻烦,您可以使用asyncio.create_task

import asyncio
from asgiref.sync import sync_to_async
from adrf.views import APIView

@sync_to_async
def sensitive_sync_function():
    count = 0
    while True:
        count = count + 1
        print("Running in Async mode !")
        time.sleep(1)
        if count == 10:
            print("Processing done !")
            break
    return None

class AsyncGroupManagementView(APIView):
    async def get(self, request, format=None):
        asyncio.create_task(sensitive_sync_function())  # note the ()
        return Response(response, status=status.HTTP_200_OK, headers=headers)

字符串
请注意,一旦sensitive_sync_function运行,它仍然会阻塞线程。您应该将其转换为xmlc并使用asyncio.sleep而不是time.sleep
最后,使用适当的ASGI服务器运行应用程序非常重要。
要在开发过程中使用ASGI,请安装Daphne服务器,它自带runserver命令:

$ pip install daphne


编辑您的settings.py

INSTALLED_APPS = [
    "daphne",  # <---
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    ...
]

...

ASGI_APPLICATION = "yourproject.asgi.application"  # <---


现在,python manage.py runserver应该可以正常运行应用程序了。

6ie5vjzr

6ie5vjzr2#

sync_to_async函数基本上是一个装饰器,当你给予它一个函数时,它会返回一个 Package 好的decorc函数。
但是您仍然需要自己执行返回的async_function
现在,既然你提到你想在不等待async_function完成运行的情况下返回响应,这意味着你不能使用await语句来执行它。
因此,您必须使用事件循环的create_task()函数来稍后运行async_function

async def get(self, request, format=None):
    async_function = sync_to_async(sensitive_sync_function)

    loop = asyncio.get_event_loop()
    # now ask the even loop to schedule your coroutine's execution
    loop.create_task(async_function())
    
    return Response(...)

字符串
一些提示:

  • 要“立即”执行协程并等待结果,请使用await语句。
  • 要在以后执行协程而不等待它完成,请使用事件循环的create_task()函数。

相关问题