开发者

Making errors abort EventMachine process

I'm working on creating a background script that uses EventMachine to connect to a server with WebSockets. The script will be run using DelayedJob or Resque. I've been able to get it to talk to the WebSockets server and send messages, but whenever an error is raised within the EventMachine loop it doesn't crash the script - which is what should happen (and what I need to have happen). I don't have to use EventMachine as I'm only sending WebSocket messages and not receiving them - but I'd love any help on this :) thank you!

#!/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_statu开发者_如何转开发s :succeeded
  end
end

Job.perform


Since you're causing an exception inside a thread, you should set Thread.abort_on_exception to true otherwise these errors will not be raised properly.


You don't need to use Thread.new here at all, in fact, it's not thread safe to do so (eventmachine itself is not thread safe, except for EM::Queue, EM::Channel and EM.schedule).

If you wanted to do synchronous things in execute, and you must have that thread, then, you'll want to call h.send via EM.schedule, for example:

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

If you must have that thread in this way, then, you want to catch exceptions from the thread you spawn yourself. You should then stop and shutdown on your own, or just raise back up in the main (eventmachine) thread:

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

The above pattern can easily just enumerate an array of threads in the periodic timer instead, if appropriate.

Finally, please note that exception bubbling (correct exception reporting) was only supported in EventMachine > 1.0, which is still in beta. To get usable backtraces when exceptions occur, either gem install eventmachine --pre, or better, use master from the Github repo.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜