В случае ошибки прервать процесс EventMachine - PullRequest
0 голосов
/ 10 сентября 2010

Я работаю над созданием фонового скрипта, который использует EventMachine для подключения к серверу с помощью WebSockets. Скрипт будет запущен с использованием DelayedJob или Resque. Мне удалось заставить его общаться с сервером WebSockets и отправлять сообщения, но всякий раз, когда в цикле EventMachine возникает ошибка, сценарий не падает, что и должно произойти (и то, что мне нужно, чтобы это произошло) , Мне не нужно использовать EventMachine, поскольку я только отправляю сообщения WebSocket и не получаю их - но я бы очень хотел помочь с этим :) спасибо!

#!/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

Ответы [ 2 ]

4 голосов
/ 16 ноября 2010

Поскольку вы вызываете исключение внутри потока, вам следует установить Thread.abort_on_exception на true, иначе эти ошибки не будут отображаться должным образом.

0 голосов
/ 25 апреля 2012

Вам вообще не нужно использовать Thread.new здесь, на самом деле это не безопасно для потоков (сам механизм обработки событий не безопасен для потоков, за исключением EM :: Queue, EM :: Channel и EM.schedule).

Если вы хотите выполнять синхронные действия в execute, и у вас должен быть этот поток, то вы захотите вызвать h.send через EM.schedule, например:

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.

...