我应该如何为从Django调用的长时间进程存储状态?

bou*_*ard 5 python django asynchronous amazon-s3 pyro

我正在开发一个允许用户上传文件的Django应用程序.我需要在将这些文件发送到Amazon S3之前对这些文件执行一些服务器端处理.在阅读了对这个问题本博客文章的回复之后,我决定处理这个问题的最佳方式是让我的视图处理程序在Pyro远程对象上调用一个方法来异步执行处理,然后立即将Http 200返回给客户端.我有这个原型的,它似乎运作良好,但是,我也想保存处理的状态,使客户可以轮询应用程序,查看该文件已被处理并上传到S3.

我可以很容易地处理轮询,但我不确定存储进程状态的适当位置.它需要由Pyro进程写入并且可以通过我的轮询视图读取.

  • 我不愿意在数据库中添加列,这些数据应该只持续30到60秒.
  • 我曾考虑使用Django的低级缓存API并使用文件ID作为密钥,但是,我不相信这正是缓存框架的设计目标,我不确定可能存在哪些无法预料的问题.这条路线.
  • 最后,我已经考虑在Pyro对象中存储状态进行处理,但是我似乎还需要添加一个布尔"processing_complete"数据库列,以便视图知道是否从Pyro对象查询状态.

当然,还有一些数据完整性问题与数据库的解耦状态(如果服务器发生故障并且所有这些数据都在内存中会发生什么?).我将听到更多经验丰富的Web应用程序开发人员将如何处理这种状态处理.

S.L*_*ott 6

我们通过在数据库中使用"请求"表来完成此操作.

上传到达后,我们创建上传的File对象,并创建一个Request.

我们启动后台批处理器.

我们返回200"我们正在处理它"页面 - 它显示了请求及其状态.

我们的批处理器使用Django ORM.完成后,它会更新Request对象.我们可以(但不)发送电子邮件通知.大多数情况下,我们只是更新状态,以便用户可以再次登录并看到处理已完成.


Batch Server Architecture说明.

它是一个WSGI服务器,它在端口上等待批处理请求.该请求是一个带有ID号的REST POST; 批处理器在数据库中查找并处理它.

服务器由REST接口自动启动.如果它没有运行,我们就会产生它.这使得用户交易看起来很慢,但是,哦.它不应该崩溃.

此外,我们有一个简单的crontab来检查它是否正在运行.在"你还活着吗?"之间最多会缩短30分钟.检查.我们没有正式的启动脚本(我们在带有mod_wsgi的Apache下运行),但我们可能会创建一个触发WSGI文件的"重启"脚本,然后对执行运行状况检查的URL执行POST(并启动批处理器).

当批处理服务器启动时,可能存在从未获得过POST的未处理请求.因此,默认启动是将所有工作从请求队列中拉出来 - 假设它可能遗漏了某些东西.


Bar*_*ski 5

我知道这是一个古老的问题,但有人可能会发现我的答案在这段时间后仍然有用,所以这里有.

当然,您可以将数据库用作队列,但是有针对该目的开发的解决方案.

AMQP就是为此而制造的.与CeleryCarrot以及RabbitMQZeroMQ等经纪服务器一起使用.

这就是我们在最新项目中使用的内容,它运作良好.

对于你的问题,芹菜和RabbitMQ似乎是最合适的.RabbitMQ提供了消息的持久性,Celery为轮询提供了简单的视图,以检查并行运行的进程的状态.

您可能也对八爪鱼感兴趣.