正如我在标题中所说的,我希望有一个任务在后台运行,处理一个大型数据库查询,同时处理来自前端的请求。我甚至可以用async/asyncio做到这一点吗?我被告知这是可能的...
出于上下文的目的,我想做一些类似下面的事情,还要注意,我并不真的需要函数告诉我什么时候完成(尽管我确实想知道这是否可能),因为我只是检查.json文件是否最终被写入。
def post_data_view(request):
if request.method == 'POST':
...
do_long_query_in_the_background(some_data)
return HttpResponse('Received. Ask me in a while if I finished.')
def is_it_done_view(request):
if request.method == 'GET':
data = find_json()
if data:
return JsonResponse(data)
else:
return HttpResponse('Not yet dude...')
async def do_long_query_in_the_background(data):
# do some long processing...
# dump the result to a result.json
return
有人告诉我这是可以用异步的,但我真的觉得很难理解。对于上下文,我试图简化很多,即使这样,我发现我不太明白发生了什么:
async def f():
while True:
print(0)
await asyncio.sleep(2)
asyncio.create_task(f())
即使我尝试的这段代码也失败了sys:1: RuntimeWarning: coroutine 'f' was never awaited
,但它确实可以在控制台上工作,我不明白为什么会这样。
我还想知道,如果这是在所有可能和安全的线程做也许?
我对此感到非常沮丧,因为在其他线程中建议的一般解决方案似乎只是使用celery ,但对于一个并不那么复杂的问题来说,它确实感觉像是矫枉过正。
3条答案
按热度按时间utugiqy61#
asyncio的
run
方法设置事件循环并创建Task
对象,调度它运行并等待它完成,然后再执行任何其他代码。虽然看起来很简单,异步编程需要一个非常不同的编程方法,因为事情可以以任何顺序发生,你必须非常仔细地考虑什么顺序是重要的函数完成。
对于您的用例,您可以使用
threading
。您可以创建一个新线程,并让它在后台运行。在线程之间切换会降低性能,但如果大部分处理在服务器端完成,您的用户可能会有更好的体验。mftmpeh82#
1.您需要使用
aync
定义视图函数。在您的情况下,它应该是:async def post_data_view(request):
1.在异步视图函数中:首先需要get循环,然后在循环中创建一个任务,应该是:
4ktjp1zp3#
我有一个完美的解决方案给你。正是你想要的。这个解决方案适用于达芙妮,因为它创建了一个全局循环,你可以在其中创建新任务,而不需要启动一个新循环。
这将通过向全局循环添加一个事件来在后台运行任务。