【问题标题】:How do I run HTTP requests from a pool of threads using Celluloid?如何使用赛璐珞从线程池运行 HTTP 请求?
【发布时间】:2013-01-27 22:45:53
【问题描述】:

我正在使用 Ruby 1.9.3,并在 Mac OSX 10.7 上对其进行测试。

我有一个 Sender 类,它应该向某个 URL 发送请求:

require "celluloid"
require "curb"

class Sender
  include Celluloid

  def send(msg)    
    Curl.get($URL) do |url|
      url.headers["content-type"] = "text/html;charset=utf-8"
    end
  rescue Exception => e
    $LOG.error "[erro]-> [ #{e.message} "
  end
end

我有另一个进程应该从 RabbitMQ 队列接收消息并使用 Sender 发送请求:

 AMQP.start(:host => $AMQP_URL) do |connection|
   @channel ||= AMQP::Channel.new(connection)
   @queue   ||= @channel.queue("results")

   pool = Sender.pool

   @queue.subscribe do |metadata, body|
      msg = MessagePack.unpack(body)        
      pool.send(msg)
  end
 end

当我运行它时,我得到:

15:56:59 results.1    | I, [2013-02-12T15:56:59.422192 #44490]  INFO -- : Terminating 5 actors...
15:56:59 results.1    | E, [2013-02-12T15:56:59.422640 #44490] ERROR -- : Celluloid::PoolManager crashed!
15:56:59 results.1    | NoMethodError: undefined method `each' for nil:NilClass
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/macosx.rb:39:in `<top (required)>'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:81:in `load'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:81:in `load_file'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:43:in `block (2 levels) in load_all'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:38:in `each'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:38:in `block in load_all'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:35:in `each'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:35:in `load_all'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/collection.rb:72:in `fact'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter.rb:94:in `block (2 levels) in singletonclass'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid.rb:37:in `cores'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/pool_manager.rb:12:in `initialize'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/calls.rb:57:in `dispatch'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/actor.rb:323:in `block in handle_message'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/tasks/task_fiber.rb:22:in `block in initialize'
15:56:59 results.1    | E, [2013-02-12T15:56:59.423117 #44490] ERROR -- : Celluloid::PoolManager#finalize crashed!
15:56:59 results.1    | NoMethodError: undefined method `+' for nil:NilClass
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/pool_manager.rb:26:in `finalize'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/actor.rb:376:in `block in run_finalizer'
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/tasks/task_fiber.rb:22:in `block in initialize'
15:56:59 results.1    | I, [2013-02-12T15:56:59.424508 #44490]  INFO -- : Shutdown completed cleanly
15:56:59 results.1    | /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/macosx.rb:39:in `<top (required)>': undefined method `each' for nil:NilClass (NoMethodError)
15:56:59 results.1    |   from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:81:in `load'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:81:in `load_file'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:43:in `block (2 levels) in load_all'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:38:in `each'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:38:in `block in load_all'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:35:in `each'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/loader.rb:35:in `load_all'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter/util/collection.rb:72:in `fact'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/facter-1.6.13/lib/facter.rb:94:in `block (2 levels) in singletonclass'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid.rb:37:in `cores'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/pool_manager.rb:12:in `initialize'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/calls.rb:57:in `dispatch'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/actor.rb:323:in `block in handle_message'
15:56:59 results.1    |     from /Users/info/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/gems/1.9.1/gems/celluloid-0.12.3/lib/celluloid/tasks/task_fiber.rb:22:in `block in initialize'
15:56:59 results.1    | exited with code 1

我是否因为池管理器而做错了什么导致进程崩溃?

【问题讨论】:

  • 你得到了什么?请不要链接到其他网站,让我们追查错误信息或您问题中的图像。 当链接断开时,它最终会断开,您的问题对于寻找同一问题答案的人来说是没有意义的。
  • 好的我在这里添加了错误信息,希望这可以帮助..

标签: ruby multithreading actor celluloid


【解决方案1】:

您的答案在Reel 中得到了否定的证明。特别是在其机架处理程序中。您可以在这里深入研究并从那里对您需要的一切进行逆向工程:

Reel 是赛璐珞 (::IO) 功能的精彩演示,正是您想要的……除了相反。它通过池接收请求,这与您的情况相反。

如您所知,这里的主要内容是您正在与 PoolManager 交谈,而不是任何一个 Actor。这是您可以重新考虑方法的主要部分。考虑到这一点进行重构:

Celluloid::Actor[:reel_rack_pool] = ::Reel::RackWorker.pool(size: options[:workers], args: [self])
    ::Reel::Server.supervise_as(:reel_server, options[:host], options[:port]) do |connection|
    Celluloid::Actor[:reel_rack_pool].handle(connection.detach)
end

考虑到该代码后,请随时用新的错误或问题更新您的问题。您肯定会在 freenode (IRC) 上的#celluloid 和/或赛璐珞的邮件列表中获得帮助,赛璐珞非常活跃,充满了敬业且知识渊博的人,他们真正欢迎不习惯赛璐珞细节的人。

【讨论】:

  • 我认为我使用了错误的方法名称“send”,当我更改方法名称时一切正常,感谢您愿意在这里提供帮助
  • 您已经清楚地想到了这一点,但是这个答案很奇怪。你介意用如何做的细节来回答这个问题吗?
  • @aronchick 如果 OP 的问题仍然存在,我当然可以做到。但这使用了celluloid-0.13.2,我们现在发布了0.17.0,reel-rack 被提取,PoolManager 被提取到它自己的gem 中(尽管暂时仍包含在标准Celluloid 中)。我非常怀疑这个问题仍然存在。但你是对的,我的回答很奇怪,而且这是一个很好的问题。如果问题仍然存在,我仍然愿意尝试重现和解决问题。
  • 实际上,我在寻找有关 Http pooling 和赛璐珞的帖子时偶然发现了这一点,而这正是我希望从您的回答中找到的 :)
  • 是的,我现在是赛璐珞的一员,所以我在 GitHub 上看到了你的问题。听起来您想使用 http.rb ...如果您有问题,请联系我/我们(最好是 IRC 或 Google 组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 2012-08-30
  • 1970-01-01
  • 2016-08-07
  • 2016-01-31
  • 2013-06-04
  • 2014-12-03
相关资源
最近更新 更多