3

在我的红宝石脚本中,我使用的是赛璐珞-zmq gem。我试图在轮询器中异步运行evaluate_response,

async.evaluate_response(socket.read_multipart) 

但是,如果我从循环中删除睡眠,不知何故,那是行不通的,它没有达到“evaluate_response”方法。但是,如果我将 sleep 放在循环中,它就可以完美地工作。

require 'celluloid/zmq'

Celluloid::ZMQ.init

module Celluloid
  module ZMQ
    class Socket
      def socket
        @socket
      end
    end
  end
end

class Indefinite
  include Celluloid::ZMQ

  ## Readers
  attr_reader :dealersock,:pullsock,:pollers

  def initialize
    prepare_dealersock and prepare_pullsock and prepare_pollers
  end

  ## prepare DEALER SOCK
  def prepare_dealersock
    @dealersock = DealerSocket.new
    @dealersock.identity = "IDENTITY"
    @dealersock.connect("tcp://localhost:20482")
  end

  ## prepare PULL SOCK
  def prepare_pullsock
    @pullsock = PullSocket.new
    @pullsock.connect("tcp://localhost:20483")
  end

  ## prepare the Pollers
  def prepare_pollers
    @pollers = ZMQ::Poller.new
    @pollers.register_readable(dealersock.socket)
    @pollers.register_readable(pullsock.socket)
  end

  def run!
    loop do 
      pollers.poll ## this is blocking operation never mind though we need it
      pollers.readables.each do |socket|
        ## we know socket.read_multipart is blocking call this would give celluloid the chance to run other process in mean time.
        async.evaluate_response(socket.read_multipart)
      end
      ## If you remove the sleep the async evaluate response would never be executed.
      ## sleep 0.2
    end

  end

  def evaluate_response(message)

    ## Hmmm, the code just not reaches over here 

    puts "got message: #{message}"

    ... 

    ...
    ...
    ...
  end
end


## Code is invoked like this

Indefinite.new.run!

知道为什么会这样吗?

4

1 回答 1

1

问题已 100% 更改,因此我之前的回答无济于事。现在,问题是...

ZMQ::Poller不属于Celluloid::ZMQ

您直接使用ffi-rzmq绑定,而不是使用Celluloid::ZMQ包装,它提供套接字的事件和线程处理。

最好制作多个actor——每个socket一个——或者Celluloid::ZMQ直接在一个actor中使用,而不是破坏它。

你的演员永远没有时间处理响应

这部分使其成为以下内容的副本:

最好的答案是使用afterevery不使用loop......这是主导你的演员。

您需要:

  • 转移evaluate_response到另一个演员。
  • 将每个套接字移动到它们自己的actor。

这段代码需要分解成几个actor才能正常工作,sleep程序末尾有一个main。但在此之前,请尝试使用afterorevery代替loop.

于 2015-09-11T13:10:17.797 回答