5

bundle exec thin start -p 3111次の出力が得られます。

ラックアダプタの使用シンWebサーバー(v1.2.11コード名Bat-Shit Crazy)最大接続数を1024に設定0.0.0.0:3111でリッスン、CTRL+Cで^Cを停止

Ctrl-Cは何もしません(SIGINT)。どちらもkillしません(SIGTERM)。

この動作への参照をいくつか見つけましたが、解決策はありません。問題は、eventmachine(最新のthinにバンドルされている)、ruby 1.9.2-r290、またはlinuxカーネル(Ubuntu 10.4 LTS、2.6.38.3-linode32)のいずれかにあるようです。

それは私のプロジェクトでは起こりますが、まったく新しいRailsプロジェクトでは起こりません。

参照:

4

1 に答える 1

5

私の推測では、何かが EventMachine リアクタ ループを拘束して終了を妨げているか、何かが SIGINT をトラップしていると思われます。

前者の簡単な例として、これを に入れてconfig.ru実行しthin -p 4567 startます:

require 'thin'
require 'sinatra'
require 'eventmachine'


get '/' do
  "hello world"
end

run Sinatra::Application

EventMachine.schedule do
  trap("INT") do
    puts "Caught SIGINT"
    EventMachine.stop # this is useless
    # exit # this stops the EventMachine
  end

  i = 0
  while i < 10
    puts "EM Running"
    i += 1
    sleep 1
  end
end

SIGINT をトラップしないと、トラップして EM.stop を呼び出した場合と同じ動作になります。EM.stop (少なくとも で実行できる純粋な Ruby バージョンではEVENTMACHINE_LIBRARY="pure_ruby" thin start) は、reactor ループ内で取得される停止が要求されたことを示すフラグを設定します。リアクター ループがステップで動かなくなった場合 (上記の場合のように)、ループは終了しません。

したがって、いくつかのオプションがあります:

  1. SIGINT をトラップして終了を強制する上記の回避策を使用してください。これにより、接続が汚れた状態のままになる可能性がありますが、彼らはそれを無駄にクイック&ダーティとは呼びません;)

  2. ブロック コードを Thread または Fibre 内に配置すると、reactor を実行し続けることができます。

  3. コード内で実行時間の長いタスクまたはループを探し、これらを EventMachine 対応に変換します。em-http-request は外部 http リクエスト用の優れたライブラリであり、em-synchrony には他にもいくつかのプロトコル (データベース接続、tcp 接続プールなど) があります。上記の例では、これは簡単です。EventMachine.add_periodic_timer(1) { puts "EM Running" }

実際のコードでは、これを追跡するのは難しいかもしれませんが、スレッドを生成してそれらに参加する場所、または大きなループを探します。プロファイリング ツールは、終了しようとしたときに実行中のコードを表示するのに役立ちます。最後に、システムとライブラリのさまざまな部分を無効にして、原因がどこにあるかを突き止めることができます。

于 2011-07-20T08:49:40.610 に答える