2

私は無限ループで何かをするプログラムを持っています(それはデーモンです)。これは正常に機能します。

今、私はシントラの助けを借りてそのデーモンのためのウェブインターフェースを提供することを計画しています。sinatraコード自体も正常に機能します。しかし、ループとsinatraコードを1つのスクリプトに含めるとすぐに、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」などのコマンドは、シナトラが後でラックに応答するための情報を隠しておくだけです。無限ループは単純に開始されます。

スレッドを追加し、子スレッドでループを開始することで、これを解決できる可能性があります。これは、ループが何か軽量で、Web サーバーとメモリを少し共有することでパフォーマンスが向上する場合に、価値があるかもしれません。ただし、通常、スレッドの相互作用を扱うのはコーディングの頭痛の種です。

Web サーバーと長時間実行されるループを別々のスクリプトに分離し、独自のプロセスで実行し、ループが読み取り可能なデータをファイルやデータベースなどに出力して、Web サーバーが取得して提供できるようにする方がよい場合があります。

于 2013-02-26T17:07:59.590 に答える
1

Sinatraプロセスをデーモンとして本当に実行したい場合は、それを独自のプロセスで(したがって、独自のスクリプトで)実行することを検討してください。たとえば、デーモンgemの使用を検討してください:http://daemons.rubyforge.org/

于 2013-02-26T17:17:01.583 に答える