5

由于一些限制,我想将我当前的项目从 EventMachine/EM-Synchrony 切换到赛璐珞,但我在联系它时遇到了一些麻烦。我正在编写的项目是一个网络收割机,它应该尽可能快地抓取大量页面。

为了基本了解赛璐珞,我在本地 Web 服务器上生成了 10.000 个虚拟页面,并希望通过这个简单的赛璐珞片段抓取它们:

#!/usr/bin/env jruby --1.9

require 'celluloid'
require 'open-uri'

IDS = 1..9999
BASE_URL = "http://192.168.0.20/files"

class Crawler
  include Celluloid
  def read(id)
    url = "#{BASE_URL}/#{id}"
    puts "URL: " + url
    open(url) { |x| x.read }
  end
end

pool = Crawler.pool(size: 100)

IDS.to_a.map do |id|
   pool.future(:read, id)
end

据我了解赛璐珞,期货是获得触发请求响应的方法(类似于 EventMachine 中的回调),对吧?另一件事是,每个参与者都在自己的线程中运行,所以我需要某种批处理请求,因为 10.000 个线程会在我的 OSX 开发机器上导致错误。

所以创建一个池是要走的路,对吧?但是:上面的代码遍历了 9999 个 URL,但只有 1300 个 HTTP 请求被发送到 Web 服务器。因此,限制请求和遍历所有 URL 会出现问题。

4

1 回答 1

7

一旦创建了所有期货,您的程序可能就会退出。使用赛璐珞,未来将开始执行,但在你对未来对象调用 #value 之前,你不能保证它会完成。这也适用于池中的期货。可能您需要做的就是将其更改为以下内容:

  crawlers = IDS.to_a.map do |id|
    begin
      pool.future(:read, id)
    rescue DeadActorError, MailboxError
    end
  end

  crawlers.compact.each { |crawler| crawler.value rescue nil }
于 2012-09-05T17:13:03.557 回答