停止线程,直到芹菜任务完成

时间:2013-11-27 00:34:41

标签: python django celery

我有一个django网络服务器,以及一个用户输入信息的表单。每次表单信息更改时,我都会在我的数据库中更新模型,并且在某些时候验证某些内容时,我会在celery中创建一个长时间运行的任务,以便在用户点击下一步之前获得我的结果。

我使用Django Celery和RabbitMQ作为代理,我的问题是什么是最合适的IN CASE方式,任务仍然没有完成只是锁定django中的响应线程,直到任务是state.SUCCESSFUL我尝试使用这个AsyncResult.get方法,但它只是将线程锁定很长时间,然后给我结果。 IE它不是即时的,有没有人知道如何解决这个问题?

3 个答案:

答案 0 :(得分:5)

您可以等到结果为ready()

from time import sleep
result = some_task.apply_async(args=myargs)
while not result.ready():
    sleep(0.5)
result_output = result.get()

似乎还有一个wait(),所以你可以使用它。以下应基本上与上面的代码做同样的事情。

result = some_task.apply_async(args=myargs)
result_output = result.wait(timeout=None, interval=0.5)

答案 1 :(得分:1)

实现这一目标的一种方法是让结果在redis中等待,并使用blocking pop操作使用像会话ID这样的唯一值来获取它们,注意它的超时能力。

答案 2 :(得分:0)

我在 Celery 版本 5.1.1 / Python 3.9.5 / Django 3.2.x 上的工作示例:

def import_media():
    keys = []
    urls = []
    for obj in s3_resource.Bucket(env.str('S3_BUCKET')).objects.all():
        if obj.key.endswith(('.m4v', '.mp4', '.m4a', '.mp3')):
            keys.append(obj.key)
    for key in keys:
        url = s3_client.generate_presigned_url(
            ClientMethod='get_object',
            Params={'Bucket': env.str('S3_BUCKET'), 'Key': key},
            ExpiresIn=86400,
        )
        if not Files.objects.filter(descriptor=strip_descriptor_url_scheme(url)).exists():
            new_file = Files.objects.create(descriptor=strip_descriptor_url_scheme(url))
            new_file.save()
            urls.append(url)
    workflow = (
        group([extract_descriptor.s(url) for url in urls]).delay()
    )
    workflow.get(timeout=None, interval=0.5)
    print("hello - Further processing here")
    return None