在Celluloid :: IO中调用sleep时,为什么进程永远被阻塞

时间:2014-08-12 03:24:07

标签: ruby celluloid

我使用Celluloid::IO进行DNS查询,下面是我的代码:

require 'celluloid/io'

class MyResolver
    include Celluloid::IO

    def initialize
        @resolver = DNSResolver.new
    end 

    def resolve(domain)
        ips = @resolver.resolve domain

        #sleep 1
        return {domain: domain, ip: ips}
    end 
end

pool = MyResolver.pool(size: 5)

domains = [ 
    'www.google.com',
    ## many other record
]

futures = domains.map {|d| pool.future.resolve(d)}

futures.each do |future|
    puts "#{future.value}"
end

此代码可在几秒钟内完成。但是当我添加行sleep 1(仅用于学习目的)时,在打印一些结果后,该过程永远被阻止,这是非常奇怪的。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

sleepCelluloid中被覆盖的关键字,因此如果您想要sleep来自Ruby,请使用Kernel.sleep。但话虽如此,从0.17.0-dependent的{​​{1}}分支开始,你所描述的这个错误不存在了(不再?)。

我使用了可重现的失败案例来测试Celluoid::IO版本celluloid-pool中发布的新0.17.0 gem,并且使用 { {1}}原样。

答案 1 :(得分:0)

至少在这种情况下DNSResolver有问题,但您可以使用"线程感知DNS解析器"来自标准ruby库的Resolv - 没有任何带有~25k域数组的块。不要忘记从Resolv中捕获异常。