1

ResqueRailsアプリをワーカーの管理に使用させようとしています。ただし、ConnectionPoolgemを引き続き使用したいと思います。

私はこれをイニシャライザーに持っています:

puts ENV["REDISTOGO_URL"]

uri = (not ENV["REDISTOGO_URL"].nil?) ? URI.parse(ENV["REDISTOGO_URL"]) : nil

# at this point, debugger confirms $redis is nil
$redis = ConnectionPool::Wrapper.new(:size => 5, :timeout => 3) { 
  if uri.nil?
    Redis.connect
  else
    Redis.connect(:host => uri.host, :port => uri.port, :password => uri.password) 
  end
}

$redis # just put this in here for the debugger
       # At this point, $redis is #<Redis:0x007fb1b0036bf0>
       # when it should be an instance of ConnectionPool::Wrapper

なぜ$redisインスタンスとして返されないのか、誰かが考えていますConnectionPool::Wrapperか?

すべてのgemソースコードを検索しましたが、の値はどこにも設定されていません$redisRedisConnectionPoolのソースコードでは、それ自体の代わりにインスタンスを返す場所は見つかりませんでした。

これは、DelayedJobからResqueに切り替えた場合にのみ発生します。だから、それが問題のように思われるでしょう。しかし、私は途方に暮れています。

私はユニコーンを使用しています。これがのファイルですconfig

worker_processes 2
timeout 30
preload_app true

before_fork do |server, worker|
  # Replace with MongoDB or whatever
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.connection.disconnect!
    Rails.logger.info('Disconnected from ActiveRecord')
  end

  # If you are using Redis but not Resque, change this
  if defined?(Resque)
    Resque.redis.quit
    Rails.logger.info('Disconnected from Redis')
  end

  sleep 1
end

after_fork do |server, worker|
  # Replace with MongoDB or whatever
  if defined?(ActiveRecord::Base)
    ActiveRecord::Base.establish_connection
    Rails.logger.info('Connected to ActiveRecord')
  end

  # If you are using Redis but not Resque, change this
  if defined?(Resque)
    # Yes, commented the Resque out for debugging, still get the same problem.
    #Resque.redis = ENV['REDISTOGO_URL']
    Rails.logger.info('Connected to Redis')
  end
end

そして最後に、Procfile:

web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
worker: env TERM_CHILD=1 QUEUE=* bundle exec rake resque:work

foreman開発環境で使用しています。

どんな助けでも大歓迎です。

4

2 に答える 2

1

ドキュメントから:

ConnectionPool :: Wrapperを使用して、単一のグローバル接続をラップできます。

大規模なアプリケーションをRedisを直接使用することからsConnectionPool::Wrapperを使用することへと移行するための便利さとして、Redisへの単一の接続をラップすることを意図しているようです。ConnectionPool

を呼び出すと$redis.with、次のように#with定義されます。ConnectionPool

実際の接続プールを取得するには、

ConnectionPool::Wrapper.new(:size => 5, :timeout => 3) { #redis logic }

ConnectionPool.new(:size => 5, :timeout => 3) { #redis logic }
于 2013-04-03T15:54:58.007 に答える
1

内部的には、ConnectionPool :: Wrapperは通常のConnectionPoolオブジェクトを作成し、method_missingを使用して、ラッパーでメソッドが呼び出されるたびに、そのプールから自動的にチェックアウト/チェックインします。

このmethod_missingの使用には、、、、inspectまたはclassオブジェクトの確認やそのタイプの把握を試みるために通常使用される任意の数のメソッドの呼び出しが含まれます。

require 'connection_pool'

class MyClass
  def foo
    'bar'
  end
end

obj = MyClass.new
obj.respond_to?(:foo) # true
obj.respond_to?(:with) # false  

wrapper = ConnectionPool::Wrapper.new { MyClass.new }
wrapper.respond_to?(:foo) # true
wrapper.respond_to?(:with) # also true! 'with' is a method on ConnectionPool::Wrapper

ConnectionPool :: Wrapperのインスタンスがありますが、わかりにくいだけです。

于 2013-09-25T02:18:46.070 に答える