diff --git a/lib/resque/plugins/status/hash.rb b/lib/resque/plugins/status/hash.rb index 0fd7f4b..f7d2841 100644 --- a/lib/resque/plugins/status/hash.rb +++ b/lib/resque/plugins/status/hash.rb @@ -16,10 +16,21 @@ class Hash < ::Hash def self.create(uuid, *messages) set(uuid, *messages) redis.zadd(set_key, Time.now.to_i, uuid) - redis.zremrangebyscore(set_key, 0, Time.now.to_i - @expire_in) if @expire_in + remove_out_of_time_statuses(uuid) uuid end + def self.remove_out_of_time_statuses(uuid) + if @expire_in + statuses = redis.zrange(set_key, 0, -1, :with_scores => true) + can_remove = [] + statuses.each do |status| + can_remove << status[0] if status[0] && status[0] != uuid && redis.get(status_key(status[0])).nil? + end + can_remove.empty? || redis.zrem(set_key, can_remove) + end + end + # Get a status by UUID. Returns a Resque::Plugins::Status::Hash def self.get(uuid) val = redis.get(status_key(uuid)) diff --git a/test/test_resque_plugins_status.rb b/test/test_resque_plugins_status.rb index de4657c..3519b81 100644 --- a/test/test_resque_plugins_status.rb +++ b/test/test_resque_plugins_status.rb @@ -251,6 +251,7 @@ class TestResquePluginsStatus < Test::Unit::TestCase context "invoking killall jobs to kill a range" do setup do @uuid1 = KillableJob.create(:num => 100) + sleep 1 @uuid2 = KillableJob.create(:num => 100) Resque::Plugins::Status::Hash.killall(0,0) # only @uuid2 should be killed diff --git a/test/test_resque_plugins_status_hash.rb b/test/test_resque_plugins_status_hash.rb index 86fc0be..c5a3b9c 100644 --- a/test/test_resque_plugins_status_hash.rb +++ b/test/test_resque_plugins_status_hash.rb @@ -94,6 +94,20 @@ class TestResquePluginsStatusHash < Test::Unit::TestCase assert_nil Resque::Plugins::Status::Hash.get(uuid) end + should "not expire keys if expire_in is set but status:uuid exists" do + Resque::Plugins::Status::Hash.expire_in = 1 + uuid = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, "new status") + thread = Thread.new{loop {Resque::Plugins::Status::Hash.set(uuid,"new status")}} + thread.run + assert_contains Resque::Plugins::Status::Hash.status_ids, uuid + assert_equal "new status", Resque::Plugins::Status::Hash.get(uuid).message + sleep 2 + Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid) + assert_contains Resque::Plugins::Status::Hash.status_ids, uuid + assert_equal "new status", Resque::Plugins::Status::Hash.get(uuid).message + thread.exit + end + should "store the options for the job created" do uuid = Resque::Plugins::Status::Hash.create(Resque::Plugins::Status::Hash.generate_uuid, "new", :options => {'test' => '123'}) assert uuid