5

いくつかの制限があるため、現在のプロジェクトをEventMachine / EM-SynchronyからCelluloidに切り替えたいのですが、連絡を取るのに問題があります。私がコーディングしているプロジェクトは、大量のページをできるだけ速くクロールするWebハーベスタです。

セルロイドの基本的な理解のために、ローカル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

私がCelluloidを理解している限り、先物は(EventMachineのコールバックと比較して)実行されたリクエストの応答を取得するための方法ですよね?もう1つは、すべてのアクターが独自のスレッドで実行されるため、リクエストをバッチ処理する必要があるため、10.000スレッドでOSX開発マシンでエラーが発生する可能性があります。

それで、プールを作成することは行く方法ですよね?ただし、上記のコードは9999のURLを繰り返し処理しますが、Webサーバーに送信されるHTTPリクエストは1300のみです。そのため、リクエストを制限し、すべてのURLを反復処理すると問題が発生します。

4

1 に答える 1

7

すべての先物が作成されるとすぐに、プログラムが終了する可能性があります。Celluloidを使用すると、futureが実行を開始しますが、futureオブジェクトで#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 に答える