0

EventMachine を使用して WebSocket でサーバーに接続するバックグラウンド スクリプトの作成に取り組んでいます。スクリプトは、DelayedJob または Resque を使用して実行されます。WebSockets サーバーと通信してメッセージを送信することはできましたが、EventMachine ループ内でエラーが発生するたびに、スクリプトがクラッシュすることはありません。 . WebSocketメッセージを送信するだけで受信しないため、EventMachineを使用する必要はありません-しかし、これについて何か助けていただければ幸いです:)ありがとう!

#!/usr/bin/env ruby
require 'rubygems'
require 'eventmachine'
require 'em-http'

class Job
  include EventMachine::Deferrable

  def self.perform
    job = Job.new
    EventMachine.run {
      http = EventMachine::HttpRequest.new("ws://localhost:8080/").get :timeout => 0

      http.errback { puts "oops" }
      http.callback {
        puts "WebSocket connected!"
        http.send("Hello watcher")
      }

      http.stream { |msg| }
      job.callback { puts "done" }
      Thread.new { 
        job.execute(http)
        http.close
        EventMachine.stop
      }
    }
  end

  def execute(h)
      sleep 1
      puts "Job Runner!"
      h.send("welcome!")
      sleep 2
      asdsadsa # here I am trying to simulate an error
      sleep 1
      h.send("we are all done!")
      sleep 1
      set_deferred_status :succeeded
  end
end

Job.perform
4

2 に答える 2

4

スレッド内で例外を引き起こしているため、Thread.abort_on_exceptionを設定する必要trueがあります。そうしないと、これらのエラーが適切に発生しません。

于 2010-11-16T18:34:18.767 に答える
0

ここで Thread.new を使用する必要はまったくありません。実際、これはスレッド セーフではありません (EM::Queue、EM::Channel、および EM.schedule を除いて、eventmachine 自体はスレッド セーフではありません)。

実行時に同期処理を実行する必要があり、そのスレッドが必要な場合は、EM.schedule を介して h.send を呼び出す必要があります。次に例を示します。

EM.schedule { h.send("welcome!") }

この方法でそのスレッドを保持する必要がある場合は、自分で生成したスレッドから例外をキャッチする必要があります。次に、自分で停止してシャットダウンするか、メイン (eventmachine) スレッドで元に戻す必要があります。

EM.run do
  thread = Thread.new do
    raise 'boom'
  end
  EM.add_periodic_timer(0.1) { thread.join(0) }
end

上記のパターンは、必要に応じて、代わりに定期的なタイマーでスレッドの配列を簡単に列挙することができます。

最後に、例外バブリング (正しい例外レポート) は、まだベータ版の EventMachine > 1.0 でのみサポートされていることに注意してください。例外が発生したときに使用可能なバックトレースを取得するにgem install eventmachine --preは、Github リポジトリの master を使用します。

于 2012-04-25T05:55:57.253 に答える