Django在执行计算密集型任务时对Ajax呼叫的响应不反应



我最近使用Django为"科学计算引擎"编程我的网络界面。

我将"计算引擎"作为Python模块包装,并在Django框架内称为。

"发动机"的compute()功能需要几分钟才能运行(我使用ajax触发它(,同时,我让前端每0.5秒拨打额外的ajax来更新CPU和内存状态到前端。但是我发现服务器在compute()完成之前没有响应额外的ajax调用。

搜索后,我想我可能会使用asynchronousmultithreading

的想法

所以我像下面一样在views.py中制作功能。

def submit(request): #some prepare ........ # call the engine t = Thread(target = compute) t.start() return HttpResponse("started")

但是,直到compute()完成之前,系统仍然不会响应我的额外ajax调用("发动机"仅使用CPU的20%左右,因此剩下大量的计算功率(。

我是后端编程的新手,我不确定Django或后端服务器处理请求在内部如何。非常感谢您,如果有人可以给我一些有关如何处理这种情况的暗示。

我最终使用python subprocess

解决了这个问题

我在单独的文件中制作"计算"代码,然后使用Popen调用它。

from subprocess import Popen def submit(request): #some prepare ........ # call the engine p = Popen(["python", "compute.py", <arguments>]) return HttpResponse("started")

如建议,subprocess不是一个很好且安全的练习。该解决方案很容易实现,但是我将尝试通过使用 Celerydjango-channels将后端转换为 worker mode

从这样的视图启动线程绝不是一个好主意。

解决此问题的最常见方法是将工作委派给单独的工人/过程。除Django外,您还有另一个python过程正在寻找工作。

您可以保持简单,并使Django查看商店有关需要在磁盘或数据库中以某种格式完成的工作的信息(这是工作队列(。然后,工作过程将每秒钟一次进行一次循环检查是否可用工作。增加工人/流程的数量,以增加更多的计算能力(当然受硬件的限制(

创建工作请求的HTTP请求可以返回job_id用户可以查询以获取工作状态。工作正在进行/正在进行/完成吗?然后,也许用户也可以获取作业的结果,甚至可以获取诸如持续时间和日志之类的元数据?

也有框架可以解决此类问题,例如芹菜和Django通道。芹菜可能更容易开始,但是对于您想做的事情可能会过大。

使用这样的工人的优点是,您可以在前面有一个非常轻巧的REST API,并且可以随着需求的增加而跨多个服务器进行扩展。

最新更新