From 7438cbaf325205c11032a3eba053ddc2e91260c7 Mon Sep 17 00:00:00 2001 From: aneesh14 Date: Thu, 15 Mar 2018 11:57:05 +0530 Subject: [PATCH 1/2] added support for redis cluster --- .gitignore | 4 ++++ leaderboard/leaderboard.py | 25 ++++++++++++++++++++----- requirements.pip | 1 + 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 0dd68ca..aa0e9a3 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,7 @@ pip-log.txt .mr.developer.cfg /.project /.pydevproject + +.venv/ +.idea/ +.ipynb_checkpoints/ diff --git a/leaderboard/leaderboard.py b/leaderboard/leaderboard.py index fd2a2ca..e77ce4f 100644 --- a/leaderboard/leaderboard.py +++ b/leaderboard/leaderboard.py @@ -1,8 +1,11 @@ from __future__ import division -from redis import StrictRedis, Redis, ConnectionPool import math import sys + +from redis import StrictRedis, Redis, ConnectionPool +from rediscluster import StrictRedisCluster + if sys.version_info.major == 3: from itertools import zip_longest else: @@ -87,15 +90,26 @@ def __init__(self, leaderboard_name, **options): connection = self.options.pop('connection', None) if isinstance(connection, (StrictRedis, Redis)): self.options['connection_pool'] = connection.connection_pool + + host = self.options.pop('host', self.DEFAULT_REDIS_HOST) + port = self.options.pop('port', self.DEFAULT_REDIS_PORT) if 'connection_pool' not in self.options: self.options['connection_pool'] = self.pool( - self.options.pop('host', self.DEFAULT_REDIS_HOST), - self.options.pop('port', self.DEFAULT_REDIS_PORT), + host, + port, self.options.pop('db', self.DEFAULT_REDIS_DB), self.options.pop('pools', self.DEFAULT_POOLS), **self.options ) - self.redis_connection = Redis(**self.options) + if not self.options.get("cluster_mode", False): + self.redis_connection = Redis(**self.options) + else: + startup_nodes = [{"host": host, "port": port}] + self.redis_connection = StrictRedisCluster( + startup_nodes=startup_nodes, + decode_responses=True, + skip_full_coverage_check=True + ) def delete_leaderboard(self): ''' @@ -220,7 +234,8 @@ def rank_member_if_in( if current_score is not None: current_score = float(current_score) - if rank_conditional(self, member, current_score, score, member_data, {'reverse': self.order}): + if rank_conditional(self, member, current_score, score, member_data, + {'reverse': self.order}): self.rank_member_in(leaderboard_name, member, score, member_data) def rank_members(self, members_and_scores): diff --git a/requirements.pip b/requirements.pip index 7800f0f..613757e 100644 --- a/requirements.pip +++ b/requirements.pip @@ -1 +1,2 @@ redis +redis-py-cluster \ No newline at end of file From 93103f4200f425c4d5569b12bdfa4e97c560e9ec Mon Sep 17 00:00:00 2001 From: aneesh14 Date: Thu, 15 Mar 2018 12:34:40 +0530 Subject: [PATCH 2/2] updated docs --- README.md | 12 ++++++++++++ leaderboard/leaderboard.py | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8e2f1f1..9fcae7e 100644 --- a/README.md +++ b/README.md @@ -44,10 +44,22 @@ The default options are as follows: MEMBER_DATA_KEY = 'member_data' SCORE_KEY = 'score' RANK_KEY = 'rank' + DEFAULT_CLUSTER_MODE = False ``` You would use the option, `order=Leaderboard.ASC`, if you wanted a leaderboard sorted from lowest-to-highest score. You may also set the `order` option on a leaderboard after you have created a new instance of a leaderboard. The various `..._KEY` options above control what data is returned in the hash of leaderboard data from calls such as `leaders` or `around_me`. Finally, the `global_member_data` option allows you to control whether optional member data is per-leaderboard (`False`) or global (`True`). +### Using cluster mode + +```python +Leaderboard( + , + host=, + db=0, # only one db supported in cluster mode + cluster_mode=True +) +``` + ### Ranking members in the leaderboard Add members to your leaderboard using `rank_member`: diff --git a/leaderboard/leaderboard.py b/leaderboard/leaderboard.py index e77ce4f..9412bc9 100644 --- a/leaderboard/leaderboard.py +++ b/leaderboard/leaderboard.py @@ -33,6 +33,7 @@ class Leaderboard(object): MEMBER_DATA_KEY = 'member_data' SCORE_KEY = 'score' RANK_KEY = 'rank' + DEFAULT_CLUSTER_MODE = False @classmethod def pool(self, host, port, db, pools={}, **options): @@ -101,7 +102,7 @@ def __init__(self, leaderboard_name, **options): self.options.pop('pools', self.DEFAULT_POOLS), **self.options ) - if not self.options.get("cluster_mode", False): + if not self.options.get("cluster_mode", self.DEFAULT_CLUSTER_MODE): self.redis_connection = Redis(**self.options) else: startup_nodes = [{"host": host, "port": port}] @@ -234,8 +235,7 @@ def rank_member_if_in( if current_score is not None: current_score = float(current_score) - if rank_conditional(self, member, current_score, score, member_data, - {'reverse': self.order}): + if rank_conditional(self, member, current_score, score, member_data, {'reverse': self.order}): self.rank_member_in(leaderboard_name, member, score, member_data) def rank_members(self, members_and_scores):