Skip to content
This repository was archived by the owner on Jan 9, 2024. It is now read-only.

Commit 9c1b763

Browse files
authored
Merge pull request #296 from Grokzen/feature/redis-py-3.0
WIP: redis-py 3.0.x support
2 parents 0c81059 + a597849 commit 9c1b763

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2573
-1220
lines changed

.travis.yml

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
sudo: false
22
dist: xenial
33
language: python
4+
cache: pip
45
python:
56
- "2.7"
67
- "3.4"
78
- "3.5"
89
- "3.6"
9-
- "3.7"
1010
- "nightly"
1111
services:
1212
- redis-server
@@ -15,9 +15,12 @@ install:
1515
- "if [[ $REDIS_VERSION == '3.2' ]]; then REDIS_VERSION=3.2 make redis-install; fi"
1616
- "if [[ $REDIS_VERSION == '4.0' ]]; then REDIS_VERSION=4.0 make redis-install; fi"
1717
- "if [[ $REDIS_VERSION == '5.0' ]]; then REDIS_VERSION=5.0 make redis-install; fi"
18+
- "if [[ $TEST_PYCODESTYLE == '1' ]]; then pip install pycodestyle; fi"
1819
- pip install -r dev-requirements.txt
1920
- pip install -e .
2021
- "if [[ $HIREDIS == '1' ]]; then pip install hiredis; fi"
22+
- "pip freeze | grep redis"
23+
- "pip freeze"
2124
env:
2225
# Redis 3.0 & HIREDIS
2326
- HIREDIS=0 REDIS_VERSION=3.0
@@ -31,7 +34,7 @@ env:
3134
# Redis 5.0 & HIREDIS
3235
- HIREDIS=0 REDIS_VERSION=5.0
3336
- HIREDIS=1 REDIS_VERSION=5.0
34-
script:
37+
script:
3538
- make start
3639
- coverage erase
3740
- coverage run --source rediscluster -p -m py.test
@@ -40,6 +43,21 @@ script:
4043
after_success:
4144
- coverage combine
4245
- coveralls
46+
- "if [[ $TEST_PYCODESTYLE == '1' ]]; then pycodestyle --repeat --show-source --exclude=.venv,.tox,dist,docs,build,*.egg,redis_install .; fi"
4347
matrix:
4448
allow_failures:
4549
- python: "nightly"
50+
- python: 2.7
51+
env: TEST_PYCODESTYLE=1
52+
- python: 3.6
53+
env: TEST_PYCODESTYLE=1
54+
# python 3.7 has to be specified manually in the matrix
55+
# https://github.com/travis-ci/travis-ci/issues/9815
56+
- python: 3.7
57+
dist: xenial
58+
sudo: true
59+
env: TEST_HIREDIS=0
60+
- python: 3.7
61+
dist: xenial
62+
sudo: true
63+
env: TEST_HIREDIS=1

LICENSE

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Copyright (c) 2014-2019 Johan Andersson
2+
3+
Permission is hereby granted, free of charge, to any person
4+
obtaining a copy of this software and associated documentation
5+
files (the "Software"), to deal in the Software without
6+
restriction, including without limitation the rights to use,
7+
copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the
9+
Software is furnished to do so, subject to the following
10+
conditions:
11+
12+
The above copyright notice and this permission notice shall be
13+
included in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
23+

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ ifndef REDIS_TRIB_RB
216216
endif
217217

218218
ifndef REDIS_VERSION
219-
REDIS_VERSION=4.0.10
219+
REDIS_VERSION=5.0.5
220220
endif
221221

222222
export REDIS_CLUSTER_NODE1_CONF
@@ -378,16 +378,16 @@ redis-install:
378378

379379
benchmark:
380380
@echo ""
381-
@echo " -- Running Simple benchmark with StrictRedis lib and non cluster server --"
381+
@echo " -- Running Simple benchmark with Redis lib and non cluster server --"
382382
python benchmarks/simple.py --port 7007 --timeit --nocluster
383383
@echo ""
384-
@echo " -- Running Simple benchmark with StrictRedisCluster lib and cluster server --"
384+
@echo " -- Running Simple benchmark with RedisCluster lib and cluster server --"
385385
python benchmarks/simple.py --port 7001 --timeit
386386
@echo ""
387-
@echo " -- Running Simple benchmark with pipelines & StrictRedis lib and non cluster server --"
387+
@echo " -- Running Simple benchmark with pipelines & Redis lib and non cluster server --"
388388
python benchmarks/simple.py --port 7007 --timeit --pipeline --nocluster
389389
@echo ""
390-
@echo " -- Running Simple benchmark with StrictRedisCluster lib and cluster server"
390+
@echo " -- Running Simple benchmark with RedisCluster lib and cluster server"
391391
python benchmarks/simple.py --port 7001 --timeit --pipeline
392392

393393
ptp:

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ This client provides a client for redis cluster that was added in redis 3.0.
44

55
This project is a port of `redis-rb-cluster` by antirez, with alot of added functionality. The original source can be found at https://github.com/antirez/redis-rb-cluster
66

7-
Gitter chat room: [![Gitter](https://badges.gitter.im/Grokzen/redis-py-cluster.svg)](https://gitter.im/Grokzen/redis-py-cluster?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
8-
97
[![Build Status](https://travis-ci.org/Grokzen/redis-py-cluster.svg?branch=master)](https://travis-ci.org/Grokzen/redis-py-cluster) [![Coverage Status](https://coveralls.io/repos/Grokzen/redis-py-cluster/badge.png)](https://coveralls.io/r/Grokzen/redis-py-cluster) [![PyPI version](https://badge.fury.io/py/redis-py-cluster.svg)](http://badge.fury.io/py/redis-py-cluster)
108

119

@@ -30,19 +28,21 @@ Latest stable release from pypi
3028
$ pip install redis-py-cluster
3129
```
3230

31+
This major version of `redis-py-cluster` supports `redis-py>=3.0.0,<3.1.0`.
32+
3333

3434

3535
## Usage example
3636

3737
Small sample script that shows how to get started with RedisCluster. It can also be found in [examples/basic.py](examples/basic.py)
3838

3939
```python
40-
>>> from rediscluster import StrictRedisCluster
40+
>>> from rediscluster import RedisCluster
4141

4242
>>> # Requires at least one node for cluster discovery. Multiple nodes is recommended.
4343
>>> startup_nodes = [{"host": "127.0.0.1", "port": "7000"}]
4444

45-
>>> rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
45+
>>> rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
4646

4747
>>> rc.set("foo", "bar")
4848
True
@@ -54,7 +54,7 @@ True
5454

5555
## License & Authors
5656

57-
Copyright (c) 2013-2018 Johan Andersson
57+
Copyright (c) 2013-2019 Johan Andersson
5858

5959
MIT (See docs/License.txt file)
6060

benchmarks/simple.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
-p <port> Port on redis server [default: 7000]
1010
-n <request> Request number [default: 100000]
1111
-c <concurrent> Concurrent client number [default: 1]
12-
--nocluster If flag is set then StrictRedis will be used instead of cluster lib
12+
--nocluster If flag is set then Redis will be used instead of cluster lib
1313
--timeit Run a mini benchmark to test performance
1414
--pipeline Only usable with --timeit flag. Runs SET/GET inside pipelines.
1515
--resetlastkey Reset __last__ key
@@ -78,12 +78,13 @@ def timeit_pipeline(rc, num):
7878
if __name__ == "__main__":
7979
args = docopt(__doc__, version="0.3.1")
8080
startup_nodes = [{"host": args['--host'], "port": args['-p']}]
81+
8182
if not args["--nocluster"]:
82-
from rediscluster import StrictRedisCluster
83-
rc = StrictRedisCluster(startup_nodes=startup_nodes, max_connections=32, socket_timeout=0.1, decode_responses=True)
83+
from rediscluster import RedisCluster
84+
rc = RedisCluster(startup_nodes=startup_nodes, max_connections=32, socket_timeout=0.1, decode_responses=True)
8485
else:
85-
from redis import StrictRedis
86-
rc = StrictRedis(host=args["--host"], port=args["-p"], socket_timeout=0.1, decode_responses=True)
86+
from redis import Redis
87+
rc = Redis(host=args["--host"], port=args["-p"], socket_timeout=0.1, decode_responses=True)
8788
# create specified number processes
8889
processes = []
8990
single_request = int(args["-n"]) // int(args["-c"])
@@ -102,4 +103,4 @@ def timeit_pipeline(rc, num):
102103
for p in processes:
103104
p.join()
104105
t2 = time.time() - t1
105-
print("Tested {0}k SET & GET (each 50%) operations took: {1} seconds... {2} operations per second".format(int(args["-n"]) / 1000, t2, int(args["-n"]) / t2 * 2))
106+
print("Tested {0}k SET & GET (each 50%) operations took: {1} seconds... {2} operations per second".format(int(args["-n"]) / 1000, t2, int(args["-n"]) / t2 * 2))

dev-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ tox
99
python-coveralls
1010
ptpdb
1111
ptpython
12+
pysnooper

docs/License.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2014-2016 Johan Andersson
1+
Copyright (c) 2014-2019 Johan Andersson
22

33
Permission is hereby granted, free of charge, to any person
44
obtaining a copy of this software and associated documentation

docs/benchmarks.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ These are a few benchmarks that are designed to test specific parts of the code
88
Setup benchmarks
99
----------------
1010

11-
Before running any benchmark you should install this lib in editable mode inside a virtualenv so it can import `StrictRedisCluster` lib.
11+
Before running any benchmark you should install this lib in editable mode inside a virtualenv so it can import `RedisCluster` lib.
1212

1313
Install with
1414

1515
.. code-block:: bash
16-
16+
1717
pip install -e .
1818
1919
You also need a few redis servers to test against. You must have one cluster with at least one node on port `7001` and you must also have a non-clustered server on port `7007`.
@@ -42,18 +42,18 @@ Example output and comparison of different runmodes
4242

4343
.. code-block::
4444
45-
-- Running Simple benchmark with StrictRedis lib and non cluster server, 50 concurrent processes and total 50000*2 requests --
45+
-- Running Simple benchmark with Redis lib and non cluster server, 50 concurrent processes and total 50000*2 requests --
4646
python benchmarks/simple.py --host 127.0.0.1 --timeit --nocluster -c 50 -n 50000
4747
50.0k SET/GET operations took: 2.45 seconds... 40799.93 operations per second
4848
49-
-- Running Simple benchmark with StrictRedisCluster lib and cluster server, 50 concurrent processes and total 50000*2 requests --
49+
-- Running Simple benchmark with RedisCluster lib and cluster server, 50 concurrent processes and total 50000*2 requests --
5050
python benchmarks/simple.py --host 127.0.0.1 --timeit -c 50 -n 50000
5151
50.0k SET & GET (each 50%) operations took: 9.51 seconds... 31513.71 operations per second
5252
53-
-- Running Simple benchmark with pipelines & StrictRedis lib and non cluster server --
53+
-- Running Simple benchmark with pipelines & Redis lib and non cluster server --
5454
python benchmarks/simple.py --host 127.0.0.1 --timeit --nocluster -c 50 -n 50000 --pipeline
5555
50.0k SET & GET (each 50%) operations took: 2.1728243827819824 seconds... 46023.047602201834 operations per second
5656
57-
-- Running Simple benchmark with StrictRedisCluster lib and cluster server
57+
-- Running Simple benchmark with RedisCluster lib and cluster server
5858
python benchmarks/simple.py --host 127.0.0.1 --timeit -c 50 -n 50000 --pipeline
59-
50.0k SET & GET (each 50%) operations took: 1.7181339263916016 seconds... 58202.68051514381 operations per second
59+
50.0k SET & GET (each 50%) operations took: 1.7181339263916016 seconds... 58202.68051514381 operations per second

docs/commands.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
Implemented commands
22
====================
33

4-
This will describe all changes that StrictRedisCluster have done to make a command to work in a cluster environment.
4+
This will describe all changes that RedisCluster have done to make a command to work in a cluster environment.
55

6-
If a command is not listed here then the default implementation from `StrictRedis` in the `redis-py` library is used.
6+
If a command is not listed here then the default implementation from `Redis` in the `redis-py` library is used.
77

88

99

@@ -107,7 +107,7 @@ Either because they do not work, there is no working implementation or it is not
107107
Overridden methods
108108
------------------
109109

110-
The following methods is overridden from StrictRedis with a custom implementation.
110+
The following methods is overridden from Redis with a custom implementation.
111111

112112
They can operate on keys that exists in different hashslots and require a client side implementation to work.
113113

docs/index.rst

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
Welcome to redis-py-cluster's documentation!
77
============================================
88

9-
This project is a port of `redis-rb-cluster` by antirez, with a lot of added functionality. The original source can be found at https://github.com/antirez/redis-rb-cluster.
9+
This project is a port of `redis-rb-cluster` by antirez, with a lot of added functionality.
1010

11+
The original source can be found at https://github.com/antirez/redis-rb-cluster.
1112

12-
The source code is `available on github`_.
13+
The source code for this project is `available on github`_.
1314

1415
.. _available on github: http://github.com/grokzen/redis-py-cluster
1516

@@ -32,62 +33,87 @@ or from source code
3233
3334
3435
35-
Usage example
36+
Basic usage example
3637
-------------
3738

38-
Small sample script that shows how to get started with RedisCluster. It can also be found in the file `exmaples/basic.py`
39+
Small sample script that shows how to get started with RedisCluster. It can also be found in the file `exmaples/basic.py`.
40+
41+
Additional code examples of more advance functionality can be found in the `examples/` folder in the source code git repo.
3942

4043
.. code-block:: python
4144
42-
>>> from rediscluster import StrictRedisCluster
45+
>>> from rediscluster import RedisCluster
4346
4447
>>> # Requires at least one node for cluster discovery. Multiple nodes is recommended.
4548
>>> startup_nodes = [{"host": "127.0.0.1", "port": "7000"}]
4649
4750
>>> # Note: See note on Python 3 for decode_responses behaviour
48-
>>> rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
51+
>>> rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
4952
5053
>>> rc.set("foo", "bar")
5154
True
5255
>>> print(rc.get("foo"))
5356
'bar'
5457
55-
5658
.. note:: Python 3
5759

58-
Since Python 3 changed to Unicode strings from Python 2's ASCII, the return type of *most* commands will be binary strings, unless the class is instantiated with the option ``decode_responses=True``. In this case, the responses will be Python 3 strings (Unicode). For the init argument `decode_responses`, when set to False, redis-py-cluster will not attempt to decode the responses it receives. In Python 3, this means the responses will be of type `bytes`. In Python 2, they will be native strings (`str`). If `decode_responses` is set to True, for Python 3 responses will be `str`, for Python 2 they will be `unicode`.
60+
Since Python 3 changed to Unicode strings from Python 2's ASCII, the return type of *most* commands will be binary strings,
61+
unless the class is instantiated with the option ``decode_responses=True``.
62+
63+
In this case, the responses will be Python 3 strings (Unicode).
64+
65+
For the init argument `decode_responses`, when set to False, redis-py-cluster will not attempt to decode the responses it receives.
66+
67+
In Python 3, this means the responses will be of type `bytes`. In Python 2, they will be native strings (`str`).
68+
69+
If `decode_responses` is set to True, for Python 3 responses will be `str`, for Python 2 they will be `unicode`.
70+
5971

60-
Dependencies & supported python versions
61-
----------------------------------------
6272

63-
- Python: redis >= `2.10.2`, <= `2.10.5` is required.
64-
Older versions in the `2.10.x` series can work but using the latest one is allways recommended.
73+
Library Dependencies
74+
--------------------
75+
76+
It is always recommended to use the latest version of the dependencies of this project.
77+
78+
- Redis-py: 'redis>=3.0.0,<3.1.0' is required in this major version of this cluster lib.
6579
- Optional Python: hiredis >= `0.2.0`. Older versions might work but is not tested.
66-
- A working Redis cluster based on version >= `3.0.0` is required. Only `3.0.x` releases is supported.
80+
- A working Redis cluster based on version `>=3.0.0` is required.
6781

6882

6983

7084
Supported python versions
7185
-------------------------
7286

73-
- 2.7
87+
Python versions should follow the same supported python versions as specificed by the upstream package `redis-py`, based on what major version(s) that is specified.
88+
89+
If this library supports more then one major version line of `redis-py`, then the supported python versions must include the set of supported python versions by all major version lines.
90+
91+
- 2.7.x
7492
- 3.4.1+ (See note)
75-
- 3.5
76-
- 3.6
77-
- 3.7
93+
- 3.5.x
94+
- 3.6.x
95+
- 3.7.x
7896

7997
.. note:: Python 3.4.0
8098

81-
A segfault was found when running `redis-py` in python `3.4.0` that was introduced into the codebase in python `3.4.0`. Because of this both `redis-py` and `redis-py-cluster` will not work when running with `3.4.0`. This lib has decided to block the lib from execution on `3.4.0` and you will get a exception when trying to import the code. The only solution is to use python `3.4.1` or some other higher minor version in the `3.4` series.
99+
A segfault was found when running `redis-py` in python `3.4.0` that was introduced into the codebase in python itself in the version `3.4.0`.
100+
101+
Because of this both `redis-py` and `redis-py-cluster` will not work when running with `3.4.0`.
102+
103+
This lib has decided to block the lib from execution on `3.4.0` and you will get a exception when trying to import the code.
104+
105+
The only solution is to use python `3.4.1` or some other higher minor version in the `3.4` series.
106+
107+
When python `3.8.0` is released and when it is added to as a supported pythoon version, python 3.4.x will be removed from supported versions and this hard block will be removed from the source code.
82108

83109

84110

85-
Regarding duplicate pypi and python naming
86-
------------------------------------------
111+
Regarding duplicate package name on pypi
112+
----------------------------------------
87113

88114
It has been found that the python module name that is used in this library (rediscluster) is already shared with a similar but older project.
89115

90-
This lib will not change the naming of the module to something else to prevent collisions between the libs.
116+
This lib will `NOT` change the naming of the module to something else to prevent collisions between the libs.
91117

92118
My reasoning for this is the following
93119

@@ -116,7 +142,6 @@ The Usage Guide
116142
commands
117143
limitations-and-differences
118144
pipelines
119-
threads
120145
pubsub
121146
readonly-mode
122147

docs/license.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Licensing
22
---------
33

4-
Copyright (c) 2013-2018 Johan Andersson
4+
Copyright (c) 2013-2019 Johan Andersson
55

66
MIT (See docs/License.txt file)
77

0 commit comments

Comments
 (0)