Skip to content

Commit 9fb5aa2

Browse files
committed
Added documentation and codestyle fixes
1 parent 4459dd6 commit 9fb5aa2

File tree

7 files changed

+80
-43
lines changed

7 files changed

+80
-43
lines changed

docs/resp3_features.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,35 @@ This means that should you want to perform something, on a given push notificati
6767
>> p = r.pubsub(push_handler_func=our_func)
6868
6969
In the example above, upon receipt of a push notification, rather than log the message, in the case where specific text occurs, an IOError is raised. This example, highlights how one could start implementing a customized message handler.
70+
71+
Client-side caching
72+
-------------------
73+
74+
Client-side caching is a technique used to create high performance services.
75+
It exploits the memory available on application servers, servers that are usually distinct computers compared to the database nodes, to store some subset of the database information directly in the application side.
76+
For more information please check `official Redis documentation <https://redis.io/docs/latest/develop/use/client-side-caching/>`_.
77+
Please notice that this feature only available with RESP3 protocol enabled in sync client only. Supported in standalone, Cluster and Sentinel clients.
78+
79+
Basic usage:
80+
81+
Enable caching with default configuration:
82+
83+
.. code:: python
84+
85+
>>> import redis
86+
>>> from redis.cache import CacheConfig
87+
>>> r = redis.Redis(host='localhost', port=6379, protocol=3, cache_config=CacheConfig())
88+
89+
The same interface applies to Redis Cluster and Sentinel.
90+
91+
Enable caching with custom cache implementation:
92+
93+
.. code:: python
94+
95+
>>> import redis
96+
>>> from foo.bar import CacheImpl
97+
>>> r = redis.Redis(host='localhost', port=6379, protocol=3, cache=CacheImpl())
98+
99+
CacheImpl should implement a `CacheInterface` specified in `redis.cache` package.
100+
101+
More robust documentation soon will be available at `official Redis documentation <https://redis.io/docs/latest/>`_.

redis/cache.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import copy
2-
import time
32
from abc import ABC, abstractmethod
43
from collections import OrderedDict
54
from enum import Enum
6-
from typing import Any, Collection, Hashable, List, Optional, Union
5+
from typing import Any, List, Optional, Union
76

87

98
class CacheEntryStatus(Enum):
@@ -260,7 +259,7 @@ def touch(self, cache_key: CacheKey) -> None:
260259
self._assert_cache()
261260

262261
if self._cache.get_collection().get(cache_key) is None:
263-
raise ValueError(f"Given entry does not belong to the cache")
262+
raise ValueError("Given entry does not belong to the cache")
264263

265264
self._cache.get_collection().move_to_end(cache_key)
266265

redis/client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,10 @@ def __init__(
319319

320320
self.connection_pool = connection_pool
321321

322-
if (cache_config or cache) and self.connection_pool.get_protocol() not in [3, "3"]:
322+
if (cache_config or cache) and self.connection_pool.get_protocol() not in [
323+
3,
324+
"3",
325+
]:
323326
raise RedisError("Client caching is only supported with RESP version 3")
324327

325328
self.connection = None

redis/connection.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from urllib.parse import parse_qs, unquote, urlparse
1414

1515
from redis.cache import (
16-
CacheConfig,
1716
CacheEntry,
1817
CacheEntryStatus,
1918
CacheFactory,

redis/retry.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
import socket
2-
import time
32
from time import sleep
43
from typing import (
54
TYPE_CHECKING,
65
Any,
76
Callable,
87
Iterable,
9-
Optional,
108
Tuple,
119
Type,
1210
TypeVar,

tests/test_cache.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -982,7 +982,9 @@ def test_get_return_correct_value(self, cache_key):
982982
result = cache.get(cache_key)
983983
assert cache.set(
984984
CacheEntry(
985-
cache_key=cache_key, cache_value=b"new_val", status=CacheEntryStatus.VALID
985+
cache_key=cache_key,
986+
cache_value=b"new_val",
987+
status=CacheEntryStatus.VALID,
986988
)
987989
)
988990

tests/test_connection.py

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import types
33
from typing import Any
44
from unittest import mock
5-
from unittest.mock import patch, call, Mock
5+
from unittest.mock import call, patch
66

77
import pytest
88
import redis
@@ -16,8 +16,6 @@
1616
CacheInterface,
1717
CacheKey,
1818
DefaultCache,
19-
EvictionPolicy,
20-
EvictionPolicyInterface,
2119
LRUPolicy,
2220
)
2321
from redis.connection import (
@@ -382,7 +380,7 @@ def test_throws_error_on_cache_enable_in_resp2(self):
382380

383381
def test_throws_error_on_incorrect_cache_implementation(self):
384382
with pytest.raises(ValueError, match="Cache must implement CacheInterface"):
385-
ConnectionPool(protocol=3, cache='wrong')
383+
ConnectionPool(protocol=3, cache="wrong")
386384

387385
def test_returns_custom_cache_implementation(self, mock_cache):
388386
connection_pool = ConnectionPool(protocol=3, cache=mock_cache)
@@ -444,7 +442,7 @@ def test_clears_cache_on_disconnect(self, mock_connection, cache_conf):
444442
assert len(cache.get_collection()) == 0
445443

446444
def test_read_response_returns_cached_reply(self, mock_cache, mock_connection):
447-
mock_connection.retry = 'mock'
445+
mock_connection.retry = "mock"
448446
mock_connection.host = "mock"
449447
mock_connection.port = "mock"
450448

@@ -455,54 +453,60 @@ def test_read_response_returns_cached_reply(self, mock_cache, mock_connection):
455453
CacheEntry(
456454
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
457455
cache_value=CacheProxyConnection.DUMMY_CACHE_VALUE,
458-
status=CacheEntryStatus.IN_PROGRESS
456+
status=CacheEntryStatus.IN_PROGRESS,
459457
),
460458
CacheEntry(
461459
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
462460
cache_value=b"bar",
463-
status=CacheEntryStatus.VALID
461+
status=CacheEntryStatus.VALID,
464462
),
465463
CacheEntry(
466464
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
467465
cache_value=b"bar",
468-
status=CacheEntryStatus.VALID
466+
status=CacheEntryStatus.VALID,
469467
),
470468
CacheEntry(
471469
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
472470
cache_value=b"bar",
473-
status=CacheEntryStatus.VALID
471+
status=CacheEntryStatus.VALID,
474472
),
475473
]
476474
mock_connection.send_command.return_value = Any
477-
mock_connection.read_response.return_value = b'bar'
475+
mock_connection.read_response.return_value = b"bar"
478476
mock_connection.can_read.return_value = False
479477

480478
proxy_connection = CacheProxyConnection(mock_connection, mock_cache)
481-
proxy_connection.send_command(*['GET', 'foo'], **{'keys': ['foo']})
482-
assert proxy_connection.read_response() == b'bar'
483-
assert proxy_connection.read_response() == b'bar'
479+
proxy_connection.send_command(*["GET", "foo"], **{"keys": ["foo"]})
480+
assert proxy_connection.read_response() == b"bar"
481+
assert proxy_connection.read_response() == b"bar"
484482

485483
mock_connection.read_response.assert_called_once()
486-
mock_cache.set.assert_has_calls([
487-
call(CacheEntry(
488-
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
489-
cache_value=CacheProxyConnection.DUMMY_CACHE_VALUE,
490-
status=CacheEntryStatus.IN_PROGRESS
491-
)),
492-
call(CacheEntry(
493-
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
494-
cache_value=b"bar",
495-
status=CacheEntryStatus.VALID
496-
)),
497-
])
498-
499-
mock_cache.get.assert_has_calls([
500-
call(CacheKey(command="GET", redis_keys=("foo",))),
501-
call(CacheKey(command="GET", redis_keys=("foo",))),
502-
call(CacheKey(command="GET", redis_keys=("foo",))),
503-
call(CacheKey(command="GET", redis_keys=("foo",))),
504-
call(CacheKey(command="GET", redis_keys=("foo",))),
505-
call(CacheKey(command="GET", redis_keys=("foo",))),
506-
])
507-
484+
mock_cache.set.assert_has_calls(
485+
[
486+
call(
487+
CacheEntry(
488+
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
489+
cache_value=CacheProxyConnection.DUMMY_CACHE_VALUE,
490+
status=CacheEntryStatus.IN_PROGRESS,
491+
)
492+
),
493+
call(
494+
CacheEntry(
495+
cache_key=CacheKey(command="GET", redis_keys=("foo",)),
496+
cache_value=b"bar",
497+
status=CacheEntryStatus.VALID,
498+
)
499+
),
500+
]
501+
)
508502

503+
mock_cache.get.assert_has_calls(
504+
[
505+
call(CacheKey(command="GET", redis_keys=("foo",))),
506+
call(CacheKey(command="GET", redis_keys=("foo",))),
507+
call(CacheKey(command="GET", redis_keys=("foo",))),
508+
call(CacheKey(command="GET", redis_keys=("foo",))),
509+
call(CacheKey(command="GET", redis_keys=("foo",))),
510+
call(CacheKey(command="GET", redis_keys=("foo",))),
511+
]
512+
)

0 commit comments

Comments
 (0)