Jahir
Jahir

Reputation: 365

Redis key expiry hook/notifications in rails

I need to call a (callback)method once a Redis key got expired. Does redis(ruby gem) provide any notification mechanism or callback registration?

Any assistance will be appreciated.

Upvotes: 3

Views: 628

Answers (2)

KNejad
KNejad

Reputation: 2518

This is possible by using the Redis keyspace notifications

It is not enabled by default though. You can enable it by editing the redis.conf or running this command:

redis-cli config set notify-keyspace-events Ex

Where the E refers to keyevent events, and x refers to expired events. (more info in the redis.conf file)

This will now send an event whenever a key expires.

You can then add the following to load when starting Rails to intercept these events:

Thread.new do
  Rails.configuration.redis_client_connection_pool.with do |connection|
    redis_db = 0 # Or whatever DB you use
    connection.psubscribe("__keyevent@#{redis_db}__:expired") do |on|
      on.pmessage do |_, channel, key|
        puts "MESSAGE HAS EXPIRED: #{key}"
      end
    end
  end
rescue Redis::BaseConnectionError => error
  Rails.logger.error "Redis connection error: #{error}, retrying in 10 seconds"
  sleep 10
  retry
end

Note: You may need to make some changes depending on your setup (e.g. if you don't use the connection pools).

Upvotes: 0

erosenin
erosenin

Reputation: 1072

This is not possible because of how Redis works. Key expirations in Redis are asynchronous and there is no callback as such when a key is expired. Hence, the Ruby gem(redis-rb) does not support this functionality as such. There would probably be an alternative way to model the solution you are building.

For the sake of completeness, If you really want this behaviour, I would add that there is one way you can make this work. You can connect to the replication log of a master node and watch for DEL operations originating from key expires and then invoke the callbacks you want.

Upvotes: 1

Related Questions