2016-08-25 5 views
-1

私はRailsの初期化プログラムconfig/initializers/globals.rbにグローバル変数を持っています。この変数は単なるリストであり、Redisセットのメンバーに設定されています。何らかのジョブでグローバルRails変数を更新するには?

$listOfBannedDomains = $redis.smembers("banned_domains") 

レディスセットはしばらくして更新されます。どのように$ listOfBannedDomainsをRailsアプリケーションを再起動せずにX時間ごとにRedisに設定されているもので更新できますか?

私はリアルタイムでレディスセットから読みたいとは思わないことに注意してください。

+1

$ listOfBannedDomainsにアクセスするたびにredisから読み込みたくない理由が不思議です。 – kiddorails

+0

となる可能性があります。 –

+0

Railsをブロックせずに定数を非同期的に更新できるように、以下の回答を追加しました。 – kiddorails

答えて

2

これにEventMachineを使用して、perioidic timerを使用して、イベントループで非同期に行うことができます。

新しいレールの初期化子を作成する - config/initializers/redis_periodic.rb

$listOfBannedDomains = $redis.smembers("banned_domains") 

Thread.new { EM.run } unless EM.reactor_running? # Run the EventMachine reactor if it's not running already in a new thread. 
Signal.trap("INT") { EM.stop } 
Signal.trap("TERM") { EM.stop } 

# Add a periodic timer: 
time_interval = 5 #seconds 
EM.add_perioidic_timer(time_interval) do 
    # Update the constant by re-reading from redis 
    $listOfBannedDomains = $redis.smembers("banned_domains") 
end 

注:これは、リクエストからメインRailsのスレッドをブロックしませんし、インスタンスをレールごとにあなたは、非同期的にその操作を行うことができます。初期化子に余分な条件を追加して、これをRakeで発生させないようにすることができます(必要な場合)。

+0

このEMスレッドの実行が停止するRailsスレッドが終了したと仮定しますか? –

+0

良い点。それを逃した。同じコードを追加しました。推奨される方法は、シグナルをトラップし、メインスレッドが終了したときにEMを停止するように要求することです。 – kiddorails

1

この変数を返すためのラッパーメソッドを作成できます。最後の更新の時間を格納するための変数を追加することができます。最後の更新からの時間がX時間を超える場合は、値をRedisから更新します。

関連する問題