我有一个使用Django Channels的Django项目。
Django 2.2.10版。
Django Channels版本2.3.0。
我目前正在使用的应用程序不使用Django频道-同一项目中的其他应用程序都使用它。
我正在使用的应用程序有一个简单的视图:
def generate_usage_report(request):
time.sleep(300)
return HttpResponse("Done")
此视图正在由AJAX请求运行,因此我不在乎它需要5分钟的时间返回-用户的浏览器会显示加载栏,直到完成为止。
不幸的是,大约30秒(给予或接受)后,我在日志中得到了此信息:
WARNING Application instance <Task pending coro=<AsgiHandler.__call__() running at /opt/my_project/venv3/lib/python3.6/site-packages/channels/http.py:192> wait_for=<Future pending cb=[_chain_future.<locals>._call_check_cancel() at /usr/lib64/python3.6/asyncio/futures.py:403, <TaskWakeupMethWrapper object at 0x7f02891c44c8>()]>> for connection <WebRequest at 0x7f02891c20f0 method=GET uri=/my_requested_page clientproto=HTTP/1.0> took too long to shut down and was killed.
并且Ajax调用永远不会完成,因为函数调用会被过早终止。有没有办法让它运行直到完成?
您不应该!服务器上的time.sleep
。这是在这段时间内停止python。 python中的所有内容(包括其他视图)以及您所在的所有异步runloop。
我建议将此视图移动为通道中的AsyncHTTPConsumer,然后让用户知道您正在执行的操作不会阻止python。 (简而言之,如果您执行任何需要花费实时时间的操作,则应await
ed)。
如果您需要调用ba阻止同步代码,则可以使用:
executor = ThreadPoolExecutor()
await loop.run_in_executor(executor, your_big_blocking_funtion)