我有一个django网络服务器,以及一个用户输入信息的表单。每次表单信息更改时,我都会在我的数据库中更新模型,并且在某些时候验证某些内容时,我会在celery中创建一个长时间运行的任务,以便在用户点击下一步之前获得我的结果。
我使用Django Celery和RabbitMQ作为代理,我的问题是什么是最合适的IN CASE方式,任务仍然没有完成只是锁定django中的响应线程,直到任务是state.SUCCESSFUL我尝试使用这个AsyncResult.get方法,但它只是将线程锁定很长时间,然后给我结果。 IE它不是即时的,有没有人知道如何解决这个问题?
答案 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