有没有办法从Python [Django]进行异步函数调用?

时间:2009-08-29 23:59:54

标签: python django asynchronous

我正在创建一个Django应用程序,它可以对上传的文件进行各种长计算。我不想让用户等待处理文件 - 我只想向用户显示一个页面,读取的内容类似于“正在解析文件”。

如何从视图中进行异步函数调用?

可能看起来像这样的东西:

def view(request):
    ...
    if form.is_valid():
        form.save()
        async_call(handle_file)
    return render_to_response(...)

4 个答案:

答案 0 :(得分:7)

我建议您完全将其分开,而不是尝试通过子进程或线程来管理它。有两种方法:第一种方法是在某个地方的数据库表中设置一个标志,并定期运行一个cron作业来检查标志并执行所需的操作。

第二个选项是使用消息队列。您的文件上载过程在队列上发送消息,并且单独的侦听器接收消息并执行所需操作。我已经将RabbitMQ用于此类事情,但也可以使用其他产品。

无论哪种方式,您的用户都不必等待该过程完成,您不必担心管理子过程。

答案 1 :(得分:2)

由于django和其他异步调用的性质,我尝试过多次尝试并尝试失败。

我提出的解决方案可能有点超过你的顶层是在后台处理另一个异步服务器处理来自Web请求的消息队列并抛出一些在异步中直接从浏览器解析的chunked javascript方式(即:ajax)。

通过mod_proxy设置为最终用户提供透明的一切。

答案 2 :(得分:0)

除非你特别需要使用一个单独的进程,这似乎是S.Lott指出你的副本的其他问题的要点,来自Python标准库的threading模块(记录{{3 }})可以提供最简单的解决方案。只需确保handle_file不访问任何可能被修改的全局变量,也不要特别修改任何全局变量本身;理想情况下,它应该只通过here实例与您的其余过程进行通信;等等,关于线程的所有常见建议; - )。

答案 3 :(得分:0)

如果我没弄错的话,

线程会破坏runserver。我已经在使用mod_wsgi和runserver的请求处理程序中运行多进程了。也许有人可以告诉我为什么这是坏事:

def _bulk_action(action, objs):
    # mean ponies here

def bulk_action(request, t):

    ...
    objs = model.objects.filter(pk__in=pks)

    if request.method == 'POST':
        objs.update(is_processing=True)

        from multiprocessing import Process
        p = Process(target=_bulk_action,args=(action,objs))
        p.start()

        return HttpResponseRedirect(next_url)

    context = {'t': t, 'action': action, 'objs': objs, 'model': model}
    return render_to_response(...)

http://docs.python.org/library/multiprocessing.html

2.6的新内容