Last active
December 10, 2015 21:48
-
-
Save latompa/4497555 to your computer and use it in GitHub Desktop.
Individual set member expiry, inspired by https://github.com/antirez/redis/issues/135
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'redis' | |
# | |
# The drawback with this approach is old members are deleted as you add new, creates a bit of overhead. | |
# The whole set expires, using normal redis expiration, if you don't add anything until the last member was added | |
# | |
class ExpiringSortedSet | |
attr_reader :key | |
def initialize(args) | |
@key = args[:key] | |
@redis = args[:redis] | |
@expiry = args[:expiry] | |
end | |
def add(v) | |
created_at = Time.now.to_i | |
expire_old_set_members(created_at) | |
expire_key | |
@redis.zadd @key, created_at+@expiry, v | |
end | |
def members | |
@redis.zrangebyscore @key, Time.now.to_i, "+inf" | |
end | |
private | |
def expire_key | |
@redis.expire @key,@expiry | |
end | |
def expire_old_set_members(since) | |
@redis.zremrangebyscore @key, "-inf", since-1 | |
end | |
end | |
p "running timed test" | |
# make a set with key test:1, set members should expire within 5 seconds | |
s = ExpiringSortedSet.new(:key => "test:1", | |
:redis => (redis=Redis.new(:host => "localhost")), | |
:expiry => 5) | |
redis.del s.key | |
s.add(1) | |
sleep 3 | |
puts s.members, "^ should be 1" | |
s.add(2) | |
puts s.members, "^ should be 1, 2" | |
sleep 3 # 1 expires here | |
puts s.members, "^ should be 2" | |
s.add(3) | |
puts s.members, "^ should be 2, 3" | |
# if set isn't accessed in the next 5 seconds, the whole key expires | |
sleep 6 | |
puts s.members, "^ should be empty" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment