0

我有一个注册表单,在提交后,我想通过一些外部 API 执行一些数据验证,然后最终提交到另一个 API。我想异步执行此操作,因此提交者不会等待 10 秒来提交表单。

到目前为止,这是我的代码——它可以工作,但是如果在任务中抛出异常,用户会收到 500 错误(具体的异常是有时我使用的第三方 API 超时)。我的印象是,如果任务是异步执行的(注意 @task 装饰器并使用延迟来调用任务),那么无论函数中发生什么,都应该成功加载页面。

视图.py

from myapp.tasks import prepare_and_submit_data

def register(request):
  form = SignupForm(request.POST or None)
  if form.is_valid():

    # Async function.
    prepare_and_submit_data.delay(form.cleaned_data)

    return render(request, 'success.html', {})
  return render(request, 'signup.html', {'form': form})

任务.py

from celery.decorators import task

@task
def prepare_and_submit_data(data):
  # do some external API requests and modify data
  data = requests.post(BASE_URL, data=data).json()
  # ...

使用 try/except 子句包装 prepare_and_submit_data 的内容并记录错误的正确解决方案是什么?或者将函数的调用包装在寄存器中?

谢谢你。

4

1 回答 1

0

如果任务是异步执行的,延迟调用是非阻塞的,它只是将任务放入消息队列中,然后立即继续执行你的视图代码,这意味着无论任务成功或失败,它都可以'对视图的代码没有任何影响。此声明的例外情况是:

  • 如果任务队列由于某种原因失败,例如您的消息队列无法访问,因此无法安排任务,在这种情况下,您将在调用时遇到异常prepare_and_submit_data.delay

  • CELERY_ALWAYS_EAGER设置为True,这意味着即使您明确请求异步执行任务,它仍然会同步执行,这与您只是定期调用阻塞函数相同(prepare_and_submit_data()

我的赌注是后一种情况,您已经正确编写了代码,但上述设置强制它同步执行。不过要考虑的一件事是,几乎可以肯定,当您的视图返回响应时,您将无法获得异步任务的结果。因此,如果您打算在执行视图期间使用异步验证的结果,那么您就不需要异步运行它,您从一开始就在定期同步执行之后。但是,如果您只需要稍后使用它,一种常见的技术是使用从客户端到单独的 API 端点的定期 ajax 请求,这应该检查您的任务是否完成了它的执行并返回结果。

于 2015-06-19T08:34:07.070 回答