我从浏览器启动长时间运行的进程,并在完成后显示结果。我在我的控制器中定义了:
def runthejob
pid = Process.fork
if pid.nil? then
#Child
output = execute_one_hour_job()
update_output_in_database(output)
# Exit here as this child process shouldn't continue anymore
exit
else
#Parent
Process.detach(pid)
#send response - job started...
end
父级中的请求正确完成。但是,在child中,总是存在"500内部服务器错误"。rails报告"227192ms内完成500个内部服务器错误"。我猜发生这种情况是因为子进程的请求-响应循环没有完成,因为子进程中存在"出口"。我该如何解决这个问题?
这是执行长时间运行的流程的正确方式吗?有更好的方法吗?
当child正在运行时,如果我执行"
ps -e | grep rails
",我会看到有两个"rails server"实例。(我使用命令"rails server
"启动我的rails服务器。)ps -e | grep rails
75678 ttys002 /Users/xx/ruby-1.9.3-p194/bin/ruby script/rails server
75696 ttys002 /Users/xx/ruby-1.9.3-p194/bin/ruby script/rails server
这是否意味着有两台服务器在运行?现在如何处理这些请求?请求是否会转到第二台服务器?
谢谢你的帮助。
在生产中尝试您的代码,看看是否出现相同的错误。如果没有,那么您的错误可能来自第一个请求完成时正在清除的开发环境,而您的fork仍然需要该环境。我还没有用fork验证过这一点,但线程就是这样。
config/development.rb中的这一行将保留环境,但任何代码更改都需要重新启动服务器。
config.cache_classes = true
在rails中有很多框架可以做到这一点:DelayedJob、Resque、Sidekiq等。
你可以在railscasts上找到很多例子:http://railscasts.com/