我有一个程序,它在infinte循环中执行某些操作(它是一个守护程序)。 这很好。
现在我计划在sintra的帮助下为该守护进程提供一个Web界面。 sinatra代码本身也很好用。但是,只要我在一个脚本中使用循环和sinatra代码,sin sinat代码就会不执行。启动时没有错误消息,但未启动本地Web服务。
这里的代码被剥离了基础:
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
require_relative 'lib/functions'
do_init_env # (some init steps, no influence on the startup of sinatra)
get '/' do
erb :web
end
# infinity Loop
loop do
if File.exists? somefile
do_something
end
sleep 10
end
当禁用循环时,sinatra启动正常:
ruby ./mydaemon.rb
[2013-02-26 12:57:24] INFO WEBrick 1.3.1
[2013-02-26 12:57:24] INFO ruby 1.9.3 (2013-02-06) [armv6l-linux-eabi]
== Sinatra/1.3.5 has taken the stage on 4567 for development with backup from WEBrick
[2013-02-26 12:57:24] INFO WEBrick::HTTPServer#start: pid=13457 port=4567
^C
== Sinatra has ended his set (crowd applauds)
[2013-02-26 12:57:36] INFO going to shutdown ...
[2013-02-26 12:57:36] INFO WEBrick::HTTPServer#start done.
启用循环时:
沉默,直到打断循环:
ruby ./mydaemon.rb
^C./mydaemon.rb:39:in `sleep': Interrupt
from ./mydaemon.rb:39:in `block in <main>'
from ./mydaemon.rb:33:in `loop'
from ./mydaemon.rb:33:in `<main>
答案 0 :(得分:4)
Rack在启动时按原样运行脚本。 “get”等命令只是存储Sinatra的信息,以便稍后响应机架。任何无限循环都会开始。
你可以通过添加线程并在子线程上启动循环来解决这个问题。如果循环执行轻量级操作,通过与Web服务器共享一些内存来获得性能,这可能是值得的。但是,使用线程交互通常是编码问题。
最好将Web服务器和长时间运行的循环分离到不同的脚本中,在自己的进程中运行,并让循环将可读数据发送到例如一个文件或数据库,Web服务器可以提取和服务。
答案 1 :(得分:1)
如果您真的想要将Sinatra进程作为守护进程运行,可以考虑在自己的进程中运行它(因此也可以使用自己的脚本)。考虑例如使用守护进程gem:http://daemons.rubyforge.org/