在没有 "returning" 的情况下发送 HttpResponse(status=200) - 发送到哪里?

Send HttpResponse(status=200) without "returning" - where to send?

我正在使用 Slack Events API 来记录与我的 slackbot 的对话。

事件 API 使用 HTTP POST 将消息推送到我的 Django 服务器。 Slack 期望在 3 秒内收到 HTTP 200 响应,否则他们将重新POST 消息。

我想存储/处理事件,但我不确定处理是否会在 3 秒内完成。我想将 HTTP 状态 200 发送回 Slack,然后继续该过程,但我不知道将它发送到哪里。通常,我 return HttpResponse(status=200) 和 python 管理目的地/发送。

如何识别响应 URI?我可以发送带 urllib2HTTP Status 200 吗?

import json
import urllib2
from django.http import HttpResponse

def processEvent(event):
    # do some stuff that takes longer than 3 seconds
    return

def incomingEvent(request):
    event = json.loads(request.body)
    url = request.?????
    req = urllib2.Request(url, HttpResponse(200))
    processEvent(event)

这种流程的想法是用长流程启动异步任务,并return快速响应发送方(在本例中为 Slack 服务器)。

但是如何异步执行这个processEvent()呢?你有很多解决方案。您可以创建一个新线程并在这个新线程中将进程配置为 运行,但在使用 Django 时这不是一种很常见的方式。

查看 python 专门用于异步作业执行的库。一个非常常见的库是 celery.

最后,你的视图变成了这样:

@app.task
def processEvent(event):
    # do some stuff that takes longer than 3 seconds
    return

def incomingEvent(request):
    event = json.loads(request.body)
    processEvent.delay(event)
    return HttpResponse()

您不需要发送任何东西,这是 return 以您一直以来的方式进行响应的唯一方法 - 通过 return 在 django 中创建一个 Reponse 对象。这种 soft-realtime 是网站中的常见问题,因为通常需要 return 快速响应,否则用户(在本例中为服务)对结果不满意。

通常在这种情况下,您希望将数据保存到某处进行处理,然后 return 立即发送给客户端。基本上,您想要 异步处理 。您可以通过创建一个新线程并将其置于后台来手动执行此操作,这样调用就可以 return 立即进行,但是您可能会遇到错误,而这是一个已经解决的问题。

输入 Celery - 它专为此类异步作业而设计。编写一些函数,将它们附加到 Celery,并在 Celery 的后台调用它们,让您轻松适应 3 秒的时间限制。

当然,这需要一些设置和外部软件,但从长远来看,这是值得的 运行。但是,如果您确实受限并且需要一个穷人的解决方案,您可以快速将传入的数据保存到数据库中的某个队列中,然后使用每分钟 运行 左右的 cron 作业来花点时间处理它。