我正在尝试从Rails应用程序运行Python脚本。该脚本可以通过调用以下命令将进度更新发布到Rails服务器:
requests.post('http://127.0.0.1:3000/progress', data={'progress':'10'})
我尝试了几种方法来使Rails服务器启动Python脚本并立即继续其其余工作。它需要自由地响应用户并接收上述进度更新。
我尝试过:
在还呈现视图的控制器方法中:
system `python3 /path/to/script.py`
out, err, st = Open3.capture3('python3', 'path/to/script.py')
在每种情况下,脚本启动后,服务器基本上都会挂起,就好像它在等待一样。我仅使用 的测试脚本发送一个进度更新,然后退出,因此即使服务器正在等待它完成,也不应造成重大延迟。
这是怎么回事,如何在后台正确运行脚本,以便我的Rails服务器可以对其进行响应?
答案 0 :(得分:1)
ActiveJob应该可以工作。试试这个:
生成一个新的Job
rails g job SlowPython
将您的慢速python脚本移至app/jobs/script.py
在app/jobs/slow_python_job.rb
中打开新文件,并在python3 /app/jobs/script.py
函数中添加perform
在控制器的方法中,要其运行,添加SlowPythonJob.perform_later
现在,当您在浏览器中打开该控制器动作时,它将使作业排队并在后台运行它,同时立即运行其余动作。 ActiveJob还允许您运行SlowPythonJob.perform_now
,它将运行作业并等待其完成,然后再执行其余操作。
所有要做的就是告诉Rails通过Active Job Async Job
队列适配器执行SlowPythonJob的perform方法。这对于开发环境非常有效。请记住,您将必须设置另一个队列适配器来处理生产中的作业队列,因为如果发生崩溃,Active Job Async Job
会丢弃所有作业...而且速度不快或功能太多和其他的一样。
以下是队列适配器的列表:http://edgeapi.rubyonrails.org/classes/ActiveJob/QueueAdapters.html