2011-12-25 49 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..." 
} 

它的工作原理,我想知道爲什麼我的第一臺服務器不能正常工作

回答

1

問題出在第一臺服務器上:你從未定義過a = [],所以拋出異常。該異常本質上將終止線程處理。回調永遠不會執行,服務器永遠不會迴應。

由於EM.defer工作在一個線程中,在received_data中的聲明將不起作用。您需要在do_something方法中解救出任何在處理過程中發生的異常。

receive_data中的ensure塊也將不起作用,因爲EM.defer將立即返回並且該代碼塊將完成。 @state將永遠不會被設置爲:processing

您需要將close_connection_after_writing本身移入回調方法。

+2

添加此行可以幫助:「Thread.abort_on_exception = true」,我通常在使用線程時將其放入init文件中,我寧願發生崩潰,也不願讓線程在我不知情的情況下死亡。 – Schmurfy 2012-01-09 10:46:59