Version 5 of the Ruby Redis gem removes Redis.current

Updated . Posted . Visible to the public.

Redis.current will be removed without replacement in redis-rb 5.0.
Version 4.6.0 adds deprecation warnings for Redis.current and Redis.current=:

`Redis.current=` is deprecated and will be removed in 5.0.

If your application still uses Redis.current, you can only fix it by no longer using it. Here is how.

Redis.new when you need it

You can easily instantiate a Redis client when you need it.

There is probably already a constant like REDIS_URL that you use to configure Sidekiq or similar. So just use that one.

redis = Redis.new(url: REDIS_URL)
redis.get('example') # instead of Redis.current.get('example')
redis.close

The performance impact of instantiating is negligible.
You may obviously assign that to a local or instance variable, if you want to.

Note

Redis.new opens a connection that will not close by itself. That's fine for global(-ish) connections. However, if you're dynamically opening connections, you need to close them as well! See the suggested helper at the bottom of this card.

Test support

If you access Redis in tests, I suggest introducing a helper method. Example for RSpec:

module RedisHelpers
  def redis
    @redis ||= Redis.new(url: REDIS_URL)
  end
end

RSpec.configure do |config|
  config.include(RedisHelpers)
end

Your Tests may then say redis.get('example').

But I still want to use a global

While not suggested, you can obviously still use a global object.

$redis = Redis.new(url: REDIS_URL)

That way, it's at least clear that $redis is a shared global state.

If you're working with legacy code that depends on Redis.current and can not be upgraded, you could of course also reintroduce it through a monkey patch.

Careful with threads

If your code uses threads, or if you're using a multi-threadeded web server like Puma, sharing $redis that way means all threads use a single Redis connection and must wait for each other Show archive.org snapshot .

Using Thread.current[:redis] instead of $redis will avoid that, but that may or may not be cumbersome to use, depending on your case.

Or, use a connection pool Show archive.org snapshot that is shared across threads. That solution is a bit more complex to set up.

I don't want to close the connection manually every time

Feel free to use the following extension:

# lib/ext/redis.rb
class Redis
  def self.with_connection
    connection = new(url: REDIS_URL)
    yield(connection)
  ensure
    connection&.close
  end
end
Redis.with_connection do |redis|
  redis.get('example')
end
Arne Hartherz
Last edit
Dominik Schöler
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2022-02-11 10:11)