-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redis.current=
is deprecated and will be removed in 5.0
#38
Conversation
While running through the `README`, I noticed this deprecation warning: ./run rails db:setup # `Redis.current=` is deprecated and will be removed in 5.0. (called from: /app/config/initializers/redis.rb:1:in `<main>') # (138.5ms) CREATE DATABASE "hello_development" ENCODING = 'unicode' # Created database 'hello_development' # ... # ... # ... I have just started dabbling with your template, but from a glance it seems like you only use `Redis.current`: 1. in the redis initializer, to set the `Redis.current` value. 2. in the health-check controller, to ping redis. It seems like all other redis integrations use `REDIS_URL` directly, so they would not be impacted by leaving `Redis.current` as `nil`. Possible fixes I see include: 1. set a global `$redis` in the initializer, use that `$redis` in place of `Redis.current` or 2. in-line `Redis.new(url: ENV.fetch("REDIS_URL"))` wherever you need to I can see a case for either, but this commit implements the global variable version. I'm happy to in-line if that's the preferred pattern to establish in your template
Hi, Thanks. To my understanding this global version is basically the equivalent of There's an open issue at redis/redis-rb#1064 which goes over potential alternatives (I commented in there too). I'm torn between which option to choose. If the global approach is the same as With Puma being multi-threaded I'm just not sure how good of an option this will be. Redis is currently being used for this health check, Rails caching, Sidekiq and Action Cable. |
Hello @nickjj,
Yes, this commit would result in the same situation in a technical sense. It removes the risk of anything breaking on a future gem update, but punts a more thought-out solution into the future. I agree with the sentiment expressed in that linked issue. Namely, that the "correct" thing to do seems very application specific. So I went with the global variable solution since it seemed like that might be the easiest to migrate away from if the specific application required a more intricate interaction with redis That said, after reading your linked comment I saw you mention that your main goals are:
That got me thinking that maybe some sort of global function would be a better solution to implement. So you could do something like module SomeModule
REDIS_URL = ENV.fetch("REDIS_URL") { "redis://redis:6379/1" }
def redis(url: REDIS_URL)
Redis.new(url: url)
end
end and then wherever you need an instance you could do something like SomeModule.redis.ping This way is:
I saw that sidekiq,action cable, and the rails cache all pass the |
I didn't actually mean to close this PR, I misclicked |
I wonder if we could reach in and grab the Rails cache's instance of Redis. I guess the trade off here is a global vs creating a new Redis connection on every health check that happens to reference the endpoint that includes a Redis check. |
🤔 that does seem possible since
Edit: I went ahead and modified the code to use I also noticed the |
Redis will always be there in dev / prod, it's defined here: docker-rails-example/config/application.rb Lines 21 to 24 in 3f5e55c
I don't think we need to do any defensive programming to ensure it's available. That would mean reverting your changes in Using I'm not really sure what the trade offs are here but I have a hunch Rails defining an ability to access the Redis client is probably better than setting up a global? What do you think? |
I saw the definition in I removed the private method and everything, but this makes
I agree with you. I think it makes a lot of sense to use I don't think there is an immediate tradeoff for the If you needed to heavily use redis directly, you might need to run your "business logic redis" and "just a cache redis" into separate redis services. Which could be a pain if you've decided you needed to do that after building out a lot of code using |
Ah right, tests. That makes things a bit more complicated. I don't think we should have special code paths in our application to account for tests. Not checking Redis in tests would also be bad. I wonder what the implications would be to use Redis in our tests. As for |
Hi, I see you closed your PR recently. I heard Rails 7.1+ will support Redis 5+ so I think this issue should be addressed sooner than later. Here's what I have in an uncommit branch which is working: # config/initializers/redis.rb
module RedisClient
class << self
def current
@redis ||= Redis.new(url: ENV.fetch("REDIS_URL") { "redis://redis:6379/1" })
end
end
end Then you can call Thinking about shipping this, do you have any last minute comments before it goes in? |
I ended up rolling with it. It's commit to master at 790a6b3. |
While running through the
README
, I noticed this deprecation warning:I have just started dabbling with your template, but from a
glance it seems like you only use
Redis.current
:Redis.current
value.It seems like all other redis integrations use
REDIS_URL
directly,so they would not be impacted by leaving
Redis.current
asnil
.Possible fixes I see include:
set a global
$redis
in the initializer, use that$redis
in place ofRedis.current
or
in-line
Redis.new(url: ENV.fetch("REDIS_URL"))
wherever you need toI can see a case for either, but this commit implements the global
variable version. I'm happy to in-line if that's the preferred pattern
to establish in your template