Skip to content

Commit

Permalink
Client side caching refactoring (#3350)
Browse files Browse the repository at this point in the history
* Restructure client side caching code

Right now the client side caching code is implemented mostly on the
level of Connections, which is too low. We need to have a shared cache
across several connections.

Move the cache implementation higher, while trying to encapsulate it
better, into a `CacheMixin` class.

This is work in progress, many details still need to be taken care of!

* Temporary refactor

* Finished CacheProxyConnection implementation, added comments

* Added test cases and scheduler dependency

* Added support for RedisCluster and multi-threaded test cases

* Added support for BlockingConnectionPool

* Fixed docker-compose command

* Revert port changes

* Initial take on Sentinel support

* Remove keys option after usage

* Added condition to remove keys entry on async

* Added same keys entry removal in pipeline

* Added caching support for Sentinel

* Added locking when accesing cache object

* Rmoved keys option from options

* Removed redundant entities

* Added cache support for SSLConnection

* Moved ssl argument handling to cover cluster case

* Revert local test changes

* Fixed bug with missing async operator

* Revert accidental changes

* Added API to return cache object

* Added eviction policy configuration

* Added mark to skip test on cluster

* Removed test case that makes no sense

* Skip tests in RESP2

* Added scheduler to dev_requirements

* Codestyle changes

* Fixed characters per line restriction

* Fixed line length

* Removed blank lines in imports

* Fixed imports codestyle

* Added CacheInterface abstraction

* Removed redundant references

* Moved hardcoded values to constants, restricted dependency versions

* Changed defaults to correct values

* Added custom background scheduler, added unit testing

* Codestyle changes

* Updated RESP2 restriction

* Cahnged typing to more generic

* Restrict pytest-asyncio version to 0.23

* Added upper version limit

* Removed usntable multithreaded tests

* Removed more flacky multithreaded tests

* Fixed issue with Sentinel killing healthcheck thread before execution

* Removed cachetools dependency, added custom cache implementation

* Updated test cases

* Updated typings

* Updated types

* Revert changes

* Removed use_cache, make health_check configurable, removed retry logic around can_read()

* Revert test skip

* Added documentation and codestyle fixes

* Updated excluded wordlist

* Added health_check thread cancelling in BlockingPool

* Revert argument rename, extended documentation

* Updated NodesManager to create shared cache between all nodes

* Codestyle fixes

* Updated docs

* Added version restrictions

* Added missing property getter

* Updated Redis server version

* Skip on long exception message

* Removed keys entry as it's csc specific

* Updated exception message for CSC

* Updated condition by adding server name check

* Added test coverage for decoded responses

* Codestyle changes

* Removed background healthcheck, use connection reference approach instead

* Removed unused imports

* Fixed broken tests

* Codestyle changes

* Fixed additional broken tests

* Codestyle changes

* Increased timer to avoid flackiness

* Restrict tests cause of PyPy

* Codestyle changes

* Updated docs, convert getters function to properties, added dataclasses

---------

Co-authored-by: Gabriel Erzse <gabriel.erzse@redis.com>
  • Loading branch information
vladvildanov and gerzse authored Sep 27, 2024
1 parent 7d73d74 commit 2e46613
Show file tree
Hide file tree
Showing 30 changed files with 2,344 additions and 1,766 deletions.
1 change: 1 addition & 0 deletions .github/wordlist.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
APM
ARGV
BFCommands
CacheImpl
CFCommands
CMSCommands
ClusterNode
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# this speeds up coverage with Python 3.12: https://github.com/nedbat/coveragepy/issues/1665
COVERAGE_CORE: sysmon
REDIS_IMAGE: redis:7.4-rc2
REDIS_IMAGE: redis:latest
REDIS_STACK_IMAGE: redis/redis-stack-server:latest

jobs:
Expand Down
1 change: 0 additions & 1 deletion dev_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
black==24.3.0
cachetools
click==8.0.4
flake8-isort
flake8
Expand Down
2 changes: 0 additions & 2 deletions docs/examples/connection_examples.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@
},
{
"cell_type": "markdown",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"### By default this library uses the RESP 2 protocol. To enable RESP3, set protocol=3."
]
Expand Down
32 changes: 32 additions & 0 deletions docs/resp3_features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,35 @@ This means that should you want to perform something, on a given push notificati
>> p = r.pubsub(push_handler_func=our_func)
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.

Client-side caching
-------------------

Client-side caching is a technique used to create high performance services.
It utilizes the memory on application servers, typically separate from the database nodes, to cache a subset of the data directly on the application side.
For more information please check `official Redis documentation <https://redis.io/docs/latest/develop/use/client-side-caching/>`_.
Please notice that this feature only available with RESP3 protocol enabled in sync client only. Supported in standalone, Cluster and Sentinel clients.

Basic usage:

Enable caching with default configuration:

.. code:: python
>>> import redis
>>> from redis.cache import CacheConfig
>>> r = redis.Redis(host='localhost', port=6379, protocol=3, cache_config=CacheConfig())
The same interface applies to Redis Cluster and Sentinel.

Enable caching with custom cache implementation:

.. code:: python
>>> import redis
>>> from foo.bar import CacheImpl
>>> r = redis.Redis(host='localhost', port=6379, protocol=3, cache=CacheImpl())
CacheImpl should implement a `CacheInterface` specified in `redis.cache` package.

More comprehensive documentation soon will be available at `official Redis documentation <https://redis.io/docs/latest/>`_.
Loading

0 comments on commit 2e46613

Please sign in to comment.