Failed to save rejection from Redis

I am trying to write a function that tries to connect to Redis using the default TCP settings, and if that fails, it tries to connect to Redis via a unix socket. I intend to have one script connection that works on all my systems, some of which use TCP and others that use sockets.

However, I cannot get rid of the failed TCP connection. Here is my test script.

require "redis" def r begin $redis ||= Redis.new rescue $redis = Redis.new(:path => "/tmp/redis.sock") end end puts "You have #{r.keys.count} redis keys" 

The rescue block never starts, and an exception is thrown instead. Here is the output of this script.

  /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:236:in `rescue in establish_connection ': Connection refused - Unable to connect to Redis on 127.0.0.1:6379 (Errno :: ECONNREFUSED)
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:222:in `establish_connection '
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:23:in `connect '
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:247:in `ensure_connected '
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:137:in `block in process'
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:206:in `logging '
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:136:in `process'
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis/client.rb:46:in `call '
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis.rb:246:in `block in keys'
     from /usr/local/rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize '
     from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/redis-2.2.2/lib/redis.rb:245:in `keys'
     from scripts / redis.rb: 11: in `<main> '

I checked that Redis.new(:path => "/tmp/redis.sock") works as expected. I tried to be more specific with my rescue unit using rescue Errno::ECONNREFUSED no avail. I am not sure why I cannot catch this exception.

Any ideas?

+7
source share
2 answers

It turns out that the exception is not raised when Redis.new called. An exception does not occur until certain methods (in this case, Redis#keys ) are called in the connection object. This revised connectivity feature seems to do the trick.

 require "redis" def r begin $redis ||= Redis.new $redis.inspect # needed to know if connection failed rescue $redis = Redis.new(:path => "/tmp/redis.sock") end $redis end 
+5
source

I found that $redis.inspect did not actually use the REDIS connection. I replaced it with $redis.keys and threw the exception correctly. Please note that I am running on Heroko and it goes into the environment variable REDISTOGO_URL . Then I have the REDIS constant that I use throughout the application.

In my config / initializers / redis.rb:

 uri = URI.parse(ENV['REDISTOGO_URL']) begin redis ||= Redis.new(:host => uri.host, :port => uri.port, :password => uri.password) redis.keys # needed to know if connection failed REDIS = redis rescue puts("Redis not loaded on #{uri.port}") REDIS = nil end 
+2
source

All Articles