Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$redis global variable with ruby on rails

I am using redis as a read cache. I have created an initializer

config/initializer/redis.rb

$redis = Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"]) 

I am using this global in my unicorn.rb to create a new connection whenever a new worker is created.

before_fork do |server, worker|   # clear redis connection   $redis.quit unless $redis.blank? end  # Give each child process its own Redis connection after_fork do |server, worker|   $redis = Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"]) end 

I am also using this global variable whenever I need to access my redis servers. But I am not comfortable using this global variable. Are there any better options than using global variable?

like image 632
Anirudhan J Avatar asked Jan 12 '14 14:01

Anirudhan J


Video Answer


2 Answers

There is Redis.current, which you can use to store your one-and-only Redis instance.

So instead of using $redis, you can assign your instance as follows:

Redis.current = Redis.new(:host => ENV["REDIS_HOST"], :port => ENV["REDIS_PORT"]) 

Redis.current was introduced to redis-rb in 2010 as a standard way to grab a redis connection, so I was surprised that no other answer mentioned it.

Update: Starting with version 4.6.0 Redis.current has been deprecated. The author notes that typical multi-threaded applications will find a lot of locking around a shared redis client. They recommend to define an own place to get a redis client, but also suggest to use a connection pool.

The accepted answer is therefore the simplest solution to achieve something comparable to Redis.current, but may not perform optimal in multi-threaded environments.

like image 158
NobodysNightmare Avatar answered Sep 19 '22 14:09

NobodysNightmare


expanding further on mestachs suggestion, namespacing a module in your initializer as below

config/initializers/redis.rb

module ReadCache   class << self     def redis       @redis ||= Redis.new(:url => (ENV["REDIS_URL"] || 'redis://127.0.0.1:6379'))     end   end end 

then in unicorn.rb

 before_fork do |server, worker|     ...    if defined?(ReadCache.redis)     ReadCache.redis.quit    end     ...  end   after_fork do |server, worker|     ...    if defined?(ReadCache.redis)     ReadCache.redis.client.reconnect    end     ...  end 
like image 40
blotto Avatar answered Sep 21 '22 14:09

blotto