Skip to content

Commit

Permalink
Add Counter#getset method which resets a counter and returns its old …
Browse files Browse the repository at this point in the history
…value.
  • Loading branch information
dv committed Sep 3, 2011
1 parent eb4485f commit 96897d1
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/redis/counter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ def reset(to=options[:start])
true # hack for redis-rb regression
end

# Reset the counter to its starting value, and return previous value.
# Use this to "reap" the counter and save it somewhere else. This is
# atomic in that no increments or decrements are lost if you process
# the returned value.
def getset(to=options[:start])
redis.getset(key, to.to_i).to_i
end

# Returns the current value of the counter. Normally just calling the
# counter will lazily fetch the value, and only update it if increment
# or decrement is called. This forces a network call to redis-server
Expand Down
7 changes: 7 additions & 0 deletions lib/redis/objects/counters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ def reset_counter(name, id=nil, to=nil)
redis.set(redis_field_key(name, id), to.to_i)
true
end

# Set a counter to its starting value and return the old value.
def getset_counter(name, id=nil, to=nil)
verify_counter_defined!(name, id)
to = @redis_objects[name][:start] if to.nil?
redis.getset(redis_field_key(name, id), to.to_i).to_i
end

private

Expand Down
4 changes: 4 additions & 0 deletions spec/redis_objects_active_record_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ class Post < ActiveRecord::Base
@ar2.total.decrement.should == 1
@ar2.total.reset
@ar2.total.should == 0
@ar2.total.reset(55)
@ar2.total.should == 55
@ar2.total.getset(12).should == 55
@ar2.total.should == 12
@ar2.destroy
end

Expand Down
2 changes: 2 additions & 0 deletions spec/redis_objects_instance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@
@counter.should == 0
@counter.reset(15).should.be.true
@counter.should == 15
@counter.getset(111).should == 15
@counter.should == 111
end

after do
Expand Down
4 changes: 4 additions & 0 deletions spec/redis_objects_model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ class CustomMethodRoster < MethodRoster
Roster.decrement_counter(:available_slots, @roster.id).should == 11
Roster.reset_counter(:available_slots, @roster.id).should == true
Roster.get_counter(:available_slots, @roster.id).should == 10
Roster.getset_counter(:available_slots, @roster.id, 555).should == 10
Roster.get_counter(:available_slots, @roster.id).should == 555
end

it "should support class-level increment/decrement of global counters" do
Expand All @@ -211,6 +213,8 @@ class CustomMethodRoster < MethodRoster
Roster.decrement_counter(:total_players_online).should == 1
Roster.reset_counter(:total_players_online).should == true
Roster.get_counter(:total_players_online).should == 0
Roster.getset_counter(:total_players_online, nil, 111).should == 0
Roster.get_counter(:total_players_online).should == 111
end

it "should take an atomic block for increment/decrement" do
Expand Down

0 comments on commit 96897d1

Please sign in to comment.