如何阻止Django频道杀死我的长时间运行的视图?

问题描述 投票:0回答:1

我有一个使用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调用永远不会完成,因为函数调用会被过早终止。有没有办法让它运行直到完成?

python django python-3.x django-channels
1个回答
0
投票

您不应该!服务器上的time.sleep。这是在这段时间内停止python。 python中的所有内容(包括其他视图)以及您所在的所有异步runloop。

我建议将此视图移动为通道中的AsyncHTTPConsumer,然后让用户知道您正在执行的操作不会阻止python。 (简而言之,如果您执行任何需要花费实时时间的操作,则应await ed)。

如果您需要调用ba阻止同步代码,则可以使用:

  executor = ThreadPoolExecutor()
  await loop.run_in_executor(executor, your_big_blocking_funtion)
© www.soinside.com 2019 - 2024. All rights reserved.