Created
October 2, 2013 14:39
-
-
Save kljensen/6794796 to your computer and use it in GitHub Desktop.
Keep track of which users are currently online in your Python app using Redis
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
| # | |
| # Demo script showing how to track which users are currently | |
| # online and what URL they're looking at using py-Redis and | |
| # ZSETs. | |
| # | |
| # Record that a user is online with | |
| # mark_user_id_active(5, url="http://foo.com/my/url/woot") | |
| # | |
| # And get a list of which users are online, and what URL they're | |
| # looking at with get_active_user_urls(). | |
| # | |
| # Obviously, you'll need to change your Redis settings ...blah blah. | |
| # License: BSD 3-clause. | |
| # | |
| import redis | |
| import time | |
| import itertools | |
| # Track online users for 60s | |
| # | |
| TIMEOUT = 60 | |
| # Keep track of when we should remove old keys from our set of | |
| # active users. We do this once every ten times, just to save | |
| # Redis memory. | |
| # | |
| time_to_purge = itertools.cycle([False] * 9 + [True]) | |
| def mark_user_id_active(user_id, url=None): | |
| """ Mark a user as "active". This means adding the user id | |
| to the 'active-users' ZSET and, if a `url` is specified, | |
| adding a separate expiring key w/ that info. | |
| """ | |
| redis_conn = redis.StrictRedis() | |
| pipe = redis_conn.pipeline() | |
| if url: | |
| # Store the URL this user is currently looking at for 60s | |
| pipe.setex("url-for-{0}".format(user_id), TIMEOUT, url) | |
| if time_to_purge.next(): | |
| pipe.zremrangebyscore('active-users', 0, inttime(-TIMEOUT)) | |
| # Store this user in our list of active users | |
| pipe.zadd('active-users', inttime(), user_id) | |
| pipe.execute() | |
| def get_active_user_ids(): | |
| """ Get a list of all users that are active | |
| """ | |
| time_end = inttime() | |
| time_start = time_end - TIMEOUT | |
| return redis_conn.zrangebyscore('active-users', time_start, time_end) | |
| def get_urls_for_user_ids(user_ids): | |
| """ Retreive the list of current URLs for a list of users that are active | |
| """ | |
| redis_conn = redis.StrictRedis() | |
| urls = [] | |
| if user_ids: | |
| urls = redis_conn.mget( | |
| ["url-for-{0}".format(user_id) for user_id in user_ids] | |
| ) | |
| return urls | |
| def get_active_user_urls(): | |
| """ Retreive a list of user ids and the URLs that those users are | |
| currently looking at... | |
| """ | |
| active_user_ids = get_active_user_ids() | |
| urls = get_active_user_ids(active_user_ids) | |
| return zip(active_user_ids, urls) |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FYI, this was copy/pasted from my project...not tested as a unit, but should work & at least shows the method.