2

我有一个程序,它在无限循环中执行某些操作(它是一个守护进程)。这工作正常。

现在我计划在sintra 的帮助下为该守护进程提供一个Web 界面。sinatra 代码本身也可以正常工作。但是,只要我在一个脚本中拥有循环和 sinatra 代码,就不会执行 sinatra 代码。启动时没有错误消息,但本地 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>
4

2 回答 2

4

Rack 在启动时按原样运行脚本。“get”等命令只是为 Sinatra 存储信息以便稍后响应 rack 。任何无限循环都会简单地开始。

您可以通过添加线程并在子线程上启动循环来解决此问题。如果循环正在做一些轻量级的事情,您可以通过与 Web 服务器共享一点内存来获得性能,这可能是值得的。但是,使用线程交互通常是一个令人头疼的编码问题。

您最好将 Web 服务器和长时间运行的循环分成不同的脚本,在它们自己的进程中运行,并让循环将可读数据发送到例如文件或数据库,Web 服务器可以获取并提供这些数据。

于 2013-02-26T17:07:59.590 回答
1

如果你真的想将 Sinatra 进程作为守护进程运行,也许可以考虑在它自己的进程中运行它(因此使用它自己的脚本)。考虑例如使用守护进程 gem:http ://daemons.rubyforge.org/

于 2013-02-26T17:17:01.583 回答