使用延迟时,EventMachine无法响应

时间:2011-12-25 14:25:54

标签: ruby 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 个答案:

答案 0 :(得分:1)

问题出在第一台服务器上:你从未定义a = [],因此引发了异常。该异常基本上将终止线程处理。回调永远不会被执行,服务器永远不会响应。

由于EM.defer适用于某个帖子,rescue中的received_data语句无效。您需要使用do_something方法进行救援,以捕获处理过程中发生的任何异常。

ensure中的receive_data块也无效,因为EM.defer将立即返回,并且该代码块将完成。 <{1}}永远不会被设置为@state之外的其他任何内容。

您需要将:processing移动到回调方法本身。