Skip to content

Commit

Permalink
Added #active_users.
Browse files Browse the repository at this point in the history
  • Loading branch information
joakimk committed Feb 11, 2012
1 parent d612da3 commit 0458a00
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 3 deletions.
6 changes: 6 additions & 0 deletions Guardfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
guard 'rspec', :version => 2, :all_on_start => false,
:all_after_pass => false, :bundler => false,
:keep_failed => false do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
end
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ In your ApplicationController:
SessionTracker.new("user", $redis).track(session[:session_id])
end

In redis, do a union on the data for the last minute to get active users:
Then to view the current state:

keys active_user*
sunion active_user_sessions_minute_12 active_user_sessions_minute_13 active_user_sessions_minute_14
SessionTracker.new("user", $redis).active_users

If redis is accessible through $redis, you don't have to give it as an argument to SessionTracker.new.

## Contributing

Expand All @@ -42,6 +42,8 @@ In redis, do a union on the data for the last minute to get active users:

## Credits and license

Inspired by [http://www.lukemelia.com/blog/archives/2010/01/17/redis-in-practice-whos-online/](http://www.lukemelia.com/blog/archives/2010/01/17/redis-in-practice-whos-online/).

By [Joakim Kolsjö](https://github.com/joakimk) under the MIT license:

> Copyright (c) 2012 Joakim Kolsjö
Expand Down
9 changes: 9 additions & 0 deletions lib/session_tracker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,16 @@ def track(id, time = Time.now)
# so we don't want to raise errors just because redis is down for a few seconds.
end

def active_users(time = Time.now)
@redis.sunion(*keys_for_last_3_minutes(time)).size
end

private

def keys_for_last_3_minutes(time)
times = 0.upto(2).map { |n| time - (n * 60) }
times.map { |t| key_for(t) }
end

def key_for(time)
"active_#{@type}_sessions_minute_#{time.strftime("%M")}"
Expand Down
16 changes: 16 additions & 0 deletions spec/session_tracker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,19 @@
end

end

describe SessionTracker, "active_users" do

let(:redis) { mock.as_null_object }

it "should do a union on the last 3 minutes to get a active user count" do
time = Time.parse("13:09")
redis.should_receive(:sunion).with("active_customer_sessions_minute_09",
"active_customer_sessions_minute_08",
"active_customer_sessions_minute_07").
and_return([ mock, mock ])

SessionTracker.new("customer", redis).active_users(time).should == 2
end

end

0 comments on commit 0458a00

Please sign in to comment.