Can't get Redis store to work
Closed this issue · 16 comments
I've added the following to my redis.rb initializer:
uri = URI.parse(ENV['REDISTOGO_URL'] || 'redis://localhost:6379')
$redis = Redis.new(host: uri.host, port: uri.port, password: uri.password)
and the following to my girl_friday.rb initializer:
SYNC_FRIENDS_QUEUE = GirlFriday::WorkQueue.new(:sync_friends, size: 2, store: GirlFriday::Store::Redis, store_config: [{ redis: $redis }]) do |msg|
Account.sync_friends(msg[:account_id])
end
However, when I push stuff to the queue (SYNC_FRIENDS_QUEUE.push(account_id: account.id))), it gets processed in memory. Tailing the Redis log shows no connected clients. Only when I do GirlFriday.status can I see the Redis client connected. Am I configuring something wrong?
You have to connect Redis after Unicorn forks. Check out http://j.mp/nu4zRR and see if that helps.
Are you able to get it working locally with the Redis store?
Redis.connect(url: ENV["REDISTOGO_URL"]
would work too, as connect can take a url
option which will be automatically parsed.
Thanks for the pointer. I added the following to my config/unicorn.rb file:
require 'redis'
after_fork do |server, worker|
$redis = Redis.connect(url: ENV['REDISTOGO_URL'] || 'redis://localhost:6379')
end
However, the queue still processes in memory. Only when I run GirlFriday.status from the console clients connect to Redis in the log.
ok, I'll try to repro soon.
Any luck reproing this yet?
Yep, using the new connect method worked! This is using the latest commit from master.
However, when I run GirlFriday.status I just get {} returned. Bug?
What's good place to configure the $redis variable so I can access it from the Rails console? Since the $redis variable is only set in config/unicorn.rb it isn't set in the console.
Wouldn't $redis be nil there anyway? Given it's set in the after_fork block inside config/unicorn.rb?
heh, yeah, duh... I suppose you could set it in an initializer or environment file if it doesn't already exist?
$redis = Redis.connect unless $redis
?
Ok, that worked. However on heroku I get this error:
irb(main):009:0> GirlFriday.status
Errno::ECONNREFUSED: Connection refused - Unable to connect to Redis on 127.0.0.1:6379
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:236:in `rescue in establish_connection'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:222:in `establish_connection'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:23:in `connect'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:247:in `ensure_connected'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:137:in `block in process'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:206:in `logging'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:136:in `process'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis/client.rb:46:in `call'
from /app/vendor/bundle/ruby/1.9.1/gems/rpm_contrib-2.1.4/lib/rpm_contrib/instrumentation/redis.rb:25:in `block in raw_call_command_with_newrelic_trace'
from /app/vendor/bundle/ruby/1.9.1/gems/newrelic_rpm-3.1.2/lib/new_relic/agent/method_tracer.rb:242:in `trace_execution_scoped'
from /app/vendor/bundle/ruby/1.9.1/gems/rpm_contrib-2.1.4/lib/rpm_contrib/instrumentation/redis.rb:23:in `raw_call_command_with_newrelic_trace'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis.rb:301:in `block in llen'
from /usr/local/lib/ruby/1.9.1/monitor.rb:201:in `mon_synchronize'
from /app/vendor/bundle/ruby/1.9.1/gems/redis-2.2.2/lib/redis.rb:300:in `llen'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.5/lib/girl_friday/persistence.rb:41:in `size'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.5/lib/girl_friday/work_queue.rb:54:in `status'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.5/lib/girl_friday.rb:43:in `block in status'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.5/lib/girl_friday.rb:41:in `each'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.5/lib/girl_friday.rb:41:in `inject'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.5/lib/girl_friday.rb:41:in `status'
from (irb):9
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in `start'
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.0.9/lib/rails/commands/console.rb:8:in `start'
from /app/vendor/bundle/ruby/1.9.1/gems/railties-3.0.9/lib/rails/commands.rb:23:in `<top (required)>'
I've set the following in config/unicorn.rb
after_fork do |server, worker|
$redis = Redis.connect url: ENV['REDISTOGO_URL']
end
Any ideas?
I'm actually seeing that too. A restart did not help. I actually wonder if using a global $redis
might be a very bad idea? @mperham have any thoughts on this? From the little bit I've found, maybe globals aren't always global, especially when dealing with threads?
@fbjork I just switched over to using connection_pool this evening instead of vanilla Redis instances. I'd love to get some feedback on how it works on Heroku. I'll be switching my app to using it tonight.
Sure, how should the configuration look like given I use unicorn?
I actually removed the after_fork
block from unicorn.rb & just configured it in my app, something like this:
require 'redis'
require 'connection_pool'
$redis = ConnectionPool.new(size: 4).new{ Redis.connect(url: ENV["REDISTOGO_URL"]) }
Q = GirlFriday::WorkQueue.new(:foo, store: GirlFriday::Store::Redis, store_config: { pool: $redis } )
I tested it out on Heroku & it worked. I'm going to close this for now, but if you have more problems please open another ticket. Thanks for all your testing, we really appreciate it!
I guess you meant to put:
$redis = ConnectionPool.new(size: 4) { Redis.connect(url: ENV["REDISTOGO_URL"]) }
When I tried to run GirlFriday.status I get this now:
LocalJumpError: no block given (yield)
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday/persistence.rb:56:in block in redis' from /app/vendor/bundle/ruby/1.9.1/gems/connection_pool-0.1.0/lib/connection_pool.rb:41:in
with'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday/persistence.rb:55:in redis' from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday/persistence.rb:44:in
size'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday/work_queue.rb:55:in status' from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday.rb:43:in
block in status'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday.rb:41:in each' from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday.rb:41:in
inject'
from /app/vendor/bundle/ruby/1.9.1/gems/girl_friday-0.9.6/lib/girl_friday.rb:41:in `status'
Please file a new issue & I'll take a look asap.