在轮询器内异步运行代码
在我的ruby脚本中,我使用的是celluloid-zmq gem。 我试图在pollers中使用异步运行evaluate_response,
async.evaluate_response(socket.read_multipart)
但是,如果我从循环中删除睡眠,不知怎么说没有成功,它没有达到“evaluate_response”方法。 但是,如果我把睡眠放在循环内,它就能很好
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!
知道为什么会这样吗?
问题是100%改变,所以我以前的答案没有帮助。 现在,问题是……
ZMQ::Poller
不是Celluloid::ZMQ
一部分
您直接使用ffi-rzmq
绑定,而不是使用Celluloid::ZMQ
包装,它提供套接字的事件和线程处理。
最好是制作多个演员 – 每个插槽一个 – 或者直接在一个演员中使用Celluloid::ZMQ
,而不是破坏它。
你的演员永远没有时间处理响应
这部分使它与以下内容重复:
- ruby块内的赛璐珞异步不起作用
最好的答案是使用
after
或every
而不是loop
…这是主宰你的演员。
你需要:
- 将
evaluate_response
移动到另一个actor。 - 将每个套接字移动到自己的actor。
这段代码需要分解成几个演员才能正常工作,并在程序结束时进行主sleep
。 但在此之前,尝试使用after
或every
而不是loop
。