与芹菜的python django种族情况

时间:2013-11-20 16:53:07

标签: python mysql django celery django-celery

在python django项目上工作,这就是我想要的:

  1. 带有对象参数的用户访问Page1,对象的函数longFunction()被触发并传递给芹菜,因此页面可以立即返回

  2. 如果用户尝试使用相同的对象参数访问Page2,我希望页面挂起,直到longFunction()触发的对象函数Page1终止。

    < / LI>

    所以我尝试通过objects.select_for_update()锁定mysql数据库行,但它不起作用。

    以下是我的代码的简化版本:

    def Page1(request, arg_id):
        obj = Vm.objects.select_for_update().get(id=arg_id)
        obj.longFunction.delay()
        return render_to_response(...)
    
    def Page2(request, arg_id):
        vm = Vm.objects.select_for_update().get(id=arg_id)
        return render_to_response(...)
    

    我希望Page2挂起vm = Vm.objects.select_for_update().get(id=arg_id)行,直到longFunction()完成。我是celery的新手,看起来在Page1返回的时候,在Page1上启动的mysql连接丢失了,即使longFunction()没有完成。

    还有其他方法可以实现吗?

    由于

2 个答案:

答案 0 :(得分:1)

也许这对你有帮助:

from celery.result import AsyncResult
from yourapp.celery import app

def Page1(request, arg_id):
    obj = Vm.objects.select_for_update().get(id=arg_id)
    celery_task_id = obj.longFunction.delay()
    return render_to_response(...)

def Page2(request, arg_id, celery_task_id):
    task = AsyncResult(app=app, id=celery_task_id)
    state = task.state
    while state != "SUCCESFUL":
        # wait or do whatever you want
    vm = Vm.objects.select_for_update().get(id=arg_id)
    return render_to_response(...)

http://docs.celeryproject.org/en/latest/reference/celery.states.html

的更多信息

答案 1 :(得分:0)

当事务关闭时(第1页),将释放select_for_update的数据库锁。这种锁不会被带到芹菜任务。您可以锁定芹菜任务,但这不会解决您的问题,因为在芹菜任务获得锁之前可能会加载第2页。

米克尔的回答将起作用。您也可以按照the celery cookbook

中的说明在缓存中设置锁定