0

Juggernautを使用して一定の間隔でデータをクライアントにプッシュする Rails アプリに取り組んでいます。コントローラー アクションを使用してプッシュを開始します。しかし、プッシュは長いプロセス (10 分以上) になることが多いため、spawn を使用してタスクをフォークしています。例えば:

def start_pushing
  spawn_block(:argv => "juggernaut-pushing") do
    for x in y
      Juggernaut.publish(stuff in here)
      sleep(30) # delay before publishing next item
    end
  end
end

問題は、start_pushing アクションを実行すると、ログ ファイルに次のエラーが表示されることです。

spawn> Exception in child[27898] - Redis::InheritedError: Tried to use a connection from a child process without reconnecting. You need to reconnect to Redis after forking.

そこで、問題が解決することを期待して、spawn_block 内に次を追加しました。

    require 'redis'
    $redis.client.disconnect
    $redis = Redis.new(:host => 'localhost', :port => 6379)

$redisをリセットするためにこれを追加する前でも、アクションは断続的に機能していましたが、修正されていないようです。おそらく $redis をリセットしても何も起こらないと思います。Juggernaut はまだ古い接続にアクセスしています。それはありそうですか?Juggernaut が新しい Redis 接続を使用していることを確認するにはどうすればよいですか?

私が説明していることについて質問があれば教えてください。私は今立ち往生しているので、助けに感謝します。

4

1 に答える 1

0

問題は、グローバル ($ で始まる変数) の使用と Passenger の使用です。すべてのグローバルは、すべてのパッセンジャー プロセスで共有されます。Redis には、redis 呼び出しのプロセス ID が接続されたプロセス ID と同じであることを確認するためのチェック機能があります。そのため、パッセンジャー ワーカー 1 を使用して redis が接続されていて、ワーカー 2 がそれを使用している場合、このエラーが発生します。

詳細については、Redis::Client クラスのメソッド connect および ensure_connected を参照してください。

解決策は、この問題で説明されています。基本的に、ここで説明されているように、memcache が好きであることを示唆しています。

つまり、config/environement.rb に以下を追加します。

if defined?(PhusionPassenger)
    PhusionPassenger.on_event(:starting_worker_process) do |forked|
        if forked
            # We're in smart spawning mode.
            $redis.reconnect
        else
            # We're in conservative spawning mode. We don't need to do anything.
        end
    end
end
于 2012-10-04T13:46:23.130 に答える