我有一个消费者通过事件订阅从队列中提取消息。它接收这些消息,然后连接到一个相当慢的 http 接口。我有一个 8 个工作池,一旦这些都被填满,我需要停止从队列中拉取请求,并让正在处理 http 作业的纤程继续工作。这是我整理的一个例子。
def send_request(callback)
EM.synchrony do
while $available <= 0
sleep 2
puts "sleeping"
end
url = 'http://example.com/api/Restaurant/11111/images/?image%5Bremote_url%5D=https%3A%2F%2Firs2.4sqi.net%2Fimg%2Fgeneral%2Foriginal%2F8NMM4yhwsLfxF-wgW0GA8IJRJO8pY4qbmCXuOPEsUTU.jpg&image%5Bsource_type_enum%5D=3'
result = EM::Synchrony.sync EventMachine::HttpRequest.new(url, :inactivity_timeout => 0).send("apost", :head => {:Accept => 'services.v1'})
callback.call(result.response)
end
end
def display(value)
$available += 1
puts value.inspect
end
$available = 8
EM.run do
EM.add_periodic_timer(0.001) do
$available -= 1
puts "Available: #{$available}"
puts "Tick ..."
puts send_request(method(:display))
end
end
我发现如果我在同步块中的一个while循环内调用睡眠,反应器循环就会卡住。如果我在 if 语句中调用 sleep (只睡一次),那么大多数情况下请求完成的时间是足够的,但充其量是不可靠的。如果我使用 EM::Synchrony.sleep,那么主反应器循环将继续创建新请求。
有没有办法暂停主循环但让纤维完成它们的执行?