2011-12-25 11 views
0

を延期EventMachineが応答これは私のサーバである

require 'rubygems' 
require 'benchmark' 
require 'eventmachine' 
class Handler < EventMachine::Connection 
    def initialize(*args) 
    super 
    end 

    def receive_data(data) 
     @state = :processing 
    EventMachine.defer(method(:do_something), method(:callback)) 
     #EM.defer(operation, callback) 
    rescue Exception => ex 
    LOGGER.error "#{ex.class}: #{ex.message}\n#{ex.backtrace.join("\n")}" 
    ensure 
    close_connection_after_writing unless @state == :processing 
    end 

    def do_something 
    #simulate a long running request 
     for i in 1..1000 
      a << rand(1000) 
      a.sort! 
     end 
     return "response from server" 
    end 

    def callback(msg) 
    self.send_data msg 
    @state = :closing 
    end 

    def unbind 
    close_connection_after_writing unless @status == :process 
    end 

end 

EventMachine::run { 
    EventMachine.epoll 
    EventMachine::start_server("0.0.0.0", 8080, Handler) 
    puts "Listening..." 
} 

を使用することができないとき、これは私は私のクライアントを実行すると、サーバはすべてのデータを受信することはできませんので、私は私を変更

require 'rubygems' 
require 'benchmark' 
require 'socket' 
require 'logger' 
Benchmark.bm do |x| 
    logger = Logger.new('test.log', 10, 1024000) 
    logger.datetime_format = "%Y-%m-%d %H:%M:%S" 
    x.report("times:") do 
    for i in 1..10 
     #Thread.new do 
     TCPSocket.open "127.0.0.1", 8080 do |s| 
      s.send "#{i}th sending\n", 0 
      if result = s.recv(100) 
      logger.info result 
      end 
      puts "#{i}th sending" 
     #end 
     end 
    end 
    end 
end 

私のクライアントでありますサーバーそれが動作

require 'rubygems' 
require 'benchmark' 
require 'eventmachine' 
class Handler < EventMachine::Connection 
    def initialize(*args) 
    super 
    end 

    def receive_data(data) 
     operation = proc do 
      # simulate a long running request 
      a = [] 
      for i in 1..1000 
       a << rand(1000) 
       a.sort! 
      end 
     end 

    # Callback block to execute once the request is fulfilled 
    callback = proc do |res| 
     send_data "data from server" 
    end 

     puts data 
     EM.defer(operation, callback) 
    end 
end 

EventMachine::run { 
    EventMachine.epoll 
    EventMachine::start_server("0.0.0.0", 8080, Handler) 
    puts "Listening..." 
} 

に従うよう、私は私の最初のサーバーが正しく

0を働くことができない理由を知りたいです

答えて

1

問題は最初のサーバーにあります。つまり、a = []を定義していないため、例外がスローされました。その例外は、本質的に、スレッド処理を終了させる。コールバックは決して実行されず、サーバーは決して応答しません。

EM.deferはスレッドで動作するため、received_datarescueステートメントは無効です。処理中に発生した例外をキャッチするには、do_somethingメソッドでレスキューが必要です。

receive_dataのブロックは、EM.deferがすぐに戻りコードブロックが完了するため、効果がありません。 @stateは、その時点で:processing以外のものに設定されることはありません。

close_connection_after_writingをコールバックメソッド自体に移動する必要があります。

+2

この行を追加すると、 "Thread.abort_on_exception = true"、スレッドで作業するときに通常は私のinitファイルに入れます。スレッドを静かに知ることなくクラッシュさせるのが好きです。 – Schmurfy