2011-12-25 30 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