Skip to content

Commit 01b52fc

Browse files
jvanascozzzeek
authored andcommitted
add lock blocking control to redis/valkey; SSL arguments
Fixes: #271 Fixes: #276 Closes: #272 Pull-request: #272 Pull-request-sha: 0b44a26 Change-Id: I680602a3abe8c9f185017c6d00b7b3c3420b3ec7
1 parent 34818c3 commit 01b52fc

File tree

5 files changed

+127
-39
lines changed

5 files changed

+127
-39
lines changed

docs/build/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# You can set these variables from the command line.
55
SPHINXOPTS =
66
SPHINXBUILD = sphinx-build
7+
AUTOBUILD = sphinx-autobuild --port 8080 --watch ../../dogpile
78
PAPER =
89
BUILDDIR = output
910

@@ -12,11 +13,12 @@ PAPEROPT_a4 = -D latex_paper_size=a4
1213
PAPEROPT_letter = -D latex_paper_size=letter
1314
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
1415

15-
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
16+
.PHONY: help clean html autobuild dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
1617

1718
help:
1819
@echo "Please use \`make <target>' where <target> is one of"
1920
@echo " html to make standalone HTML files"
21+
@echo " autobuild autobuild and run a webserver"
2022
@echo " dist-html same as html, but places files in /doc"
2123
@echo " dirhtml to make HTML files named index.html in directories"
2224
@echo " pickle to make pickle files"
@@ -36,6 +38,9 @@ html:
3638
@echo
3739
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
3840

41+
autobuild:
42+
$(AUTOBUILD) $(ALLSPHINXOPTS) $(BUILDDIR)/html
43+
3944
dist-html:
4045
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
4146
cp -R $(BUILDDIR)/html/* ../

docs/build/unreleased/271.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.. change::
2+
:tags: usecase, redis
3+
:tickets: 271
4+
5+
Added new parameters :paramref:`.RedisBackend.lock_blocking_timeout` and
6+
:paramref:`.RedisBackend.lock_blocking` to the Redis backend; and
7+
:paramref:`.ValkeyBackend.lock_blocking_timeout` and
8+
:paramref:`.ValkeyBackend.lock_blocking` to the Valkey backends. These
9+
parameters are then passed onto the redis/valkey client Lock creation
10+
methods and use the same defaults.

docs/build/unreleased/276.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.. change::
2+
:tags: usecase, redis
3+
:tickets: 276
4+
5+
Added new parameters for the Redis/Valkey backends. These params are passed
6+
directly to the constructors:
7+
8+
* :paramref:`.RedisBackend.ssl`
9+
* :paramref:`.ValkeyBackend.ssl`
10+
11+
These params default to ``None``, and are only passed to the constructor if
12+
set. The docstrings instruct users to submit all additional ``ssl_``
13+
prefixed params via the optional
14+
:paramref:`.RedisBackend.connection_kwargs` or
15+
:paramref:`.ValkeyBackend.connection_kwargs` parameter.

dogpile/cache/backends/redis.py

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Redis Backends
33
------------------
44
5-
Provides backends for talking to `Redis <http://redis.io>`_.
5+
Provides backends for talking to `Redis <http://redis.io>`__.
66
77
"""
88

@@ -22,8 +22,8 @@
2222

2323

2424
class RedisBackend(BytesBackend):
25-
r"""A `Redis <http://redis.io/>`_ backend, using the
26-
`redis-py <http://pypi.python.org/pypi/redis/>`_ driver.
25+
r"""A `Redis <http://redis.io/>`__ backend, using the
26+
`redis-py <http://pypi.python.org/pypi/redis/>`__ driver.
2727
2828
Example configuration::
2929
@@ -73,6 +73,20 @@ class RedisBackend(BytesBackend):
7373
Redis should expire it. This argument is only valid when
7474
``distributed_lock`` is ``True``.
7575
76+
:param lock_sleep: integer, number of seconds to sleep when failed to
77+
acquire a lock. This argument is only valid when
78+
``distributed_lock`` is ``True``.
79+
80+
:param lock_blocking: bool, default ``True``. Passed to the Redis client's
81+
lock constructor when ``distributed_lock`` is ``True``.
82+
83+
.. versionadded:: 1.4.1
84+
85+
:param lock_blocking_timeout: int or float, default ``None``. Passed to the
86+
Redis client's lock constructor when ``distributed_lock`` is ``True``.
87+
88+
.. versionadded:: 1.4.1
89+
7690
:param socket_timeout: float, seconds for socket timeout.
7791
Default is None (no timeout).
7892
@@ -91,10 +105,6 @@ class RedisBackend(BytesBackend):
91105
92106
.. versionadded:: 1.3.2
93107
94-
:param lock_sleep: integer, number of seconds to sleep when failed to
95-
acquire a lock. This argument is only valid when
96-
``distributed_lock`` is ``True``.
97-
98108
:param connection_pool: ``redis.ConnectionPool`` object. If provided,
99109
this object supersedes other connection arguments passed to the
100110
``redis.StrictRedis`` instance, including url and/or host as well as
@@ -106,17 +116,20 @@ class RedisBackend(BytesBackend):
106116
asynchronous runners, as they run in a different thread than the one
107117
used to create the lock.
108118
119+
:param ssl: boolean, default ``None``. If set, this is passed to the
120+
``redis.StrictRedis`` constructor as ``ssl``. All additional ``ssl_``
121+
prefixed args should be submitted via the
122+
:paramref:`.RedisBackend.connection_kwargs` dict.
123+
124+
.. versionadded:: 1.4.1
125+
109126
:param connection_kwargs: dict, additional keyword arguments are passed
110127
along to the
111128
``StrictRedis.from_url()`` method or ``StrictRedis()`` constructor
112129
directly, including parameters like ``ssl``, ``ssl_certfile``,
113130
``charset``, etc.
114131
115132
.. versionadded:: 1.1.6
116-
117-
118-
119-
120133
"""
121134

122135
def __init__(self, arguments):
@@ -128,7 +141,6 @@ def __init__(self, arguments):
128141
self.password = arguments.pop("password", None)
129142
self.port = arguments.pop("port", 6379)
130143
self.db = arguments.pop("db", 0)
131-
self.distributed_lock = arguments.pop("distributed_lock", False)
132144
self.socket_timeout = arguments.pop("socket_timeout", None)
133145
self.socket_connect_timeout = arguments.pop(
134146
"socket_connect_timeout", None
@@ -137,8 +149,19 @@ def __init__(self, arguments):
137149
self.socket_keepalive_options = arguments.pop(
138150
"socket_keepalive_options", None
139151
)
152+
153+
# additional ssl params should be submitted in `connection_kwargs`
154+
self.ssl = arguments.pop("ssl", None)
155+
156+
# used by `get_mutex`
157+
self.distributed_lock = arguments.pop("distributed_lock", False)
140158
self.lock_timeout = arguments.pop("lock_timeout", None)
141159
self.lock_sleep = arguments.pop("lock_sleep", 0.1)
160+
self.lock_blocking = arguments.pop("lock_blocking", True)
161+
self.lock_blocking_timeout = arguments.pop(
162+
"lock_blocking_timeout", None
163+
)
164+
142165
self.thread_local_lock = arguments.pop("thread_local_lock", True)
143166
self.connection_kwargs = arguments.pop("connection_kwargs", {})
144167

@@ -150,6 +173,7 @@ def __init__(self, arguments):
150173

151174
self.redis_expiration_time = arguments.pop("redis_expiration_time", 0)
152175
self.connection_pool = arguments.pop("connection_pool", None)
176+
153177
self._create_client()
154178

155179
def _imports(self):
@@ -179,6 +203,8 @@ def _create_client(self):
179203
args["socket_keepalive_options"] = (
180204
self.socket_keepalive_options
181205
)
206+
if self.ssl is not None:
207+
args["ssl"] = self.ssl
182208

183209
if self.url is not None:
184210
args.update(url=self.url)
@@ -203,6 +229,8 @@ def get_mutex(self, key):
203229
timeout=self.lock_timeout,
204230
sleep=self.lock_sleep,
205231
thread_local=self.thread_local_lock,
232+
blocking=self.lock_blocking,
233+
blocking_timeout=self.lock_blocking_timeout,
206234
)
207235
)
208236
else:
@@ -259,10 +287,10 @@ def locked(self) -> bool:
259287

260288

261289
class RedisSentinelBackend(RedisBackend):
262-
"""A `Redis <http://redis.io/>`_ backend, using the
263-
`redis-py <http://pypi.python.org/pypi/redis/>`_ driver.
290+
"""A `Redis <http://redis.io/>`__ backend, using the
291+
`redis-py <http://pypi.python.org/pypi/redis/>`__ driver.
264292
This backend is to be used when using
265-
`Redis Sentinel <https://redis.io/docs/management/sentinel/>`_.
293+
`Redis Sentinel <https://redis.io/docs/management/sentinel/>`__.
266294
267295
.. versionadded:: 1.0.0
268296
@@ -413,17 +441,17 @@ def _create_client(self):
413441

414442

415443
class RedisClusterBackend(RedisBackend):
416-
r"""A `Redis <http://redis.io/>`_ backend, using the
417-
`redis-py <http://pypi.python.org/pypi/redis/>`_ driver.
444+
r"""A `Redis <http://redis.io/>`__ backend, using the
445+
`redis-py <http://pypi.python.org/pypi/redis/>`__ driver.
418446
This backend is to be used when connecting to a
419-
`Redis Cluster <https://redis.io/docs/management/scaling/>`_ which
447+
`Redis Cluster <https://redis.io/docs/management/scaling/>`__ which
420448
will use the
421449
`RedisCluster Client
422-
<https://redis.readthedocs.io/en/stable/connections.html#cluster-client>`_.
450+
<https://redis.readthedocs.io/en/stable/connections.html#cluster-client>`__.
423451
424452
.. seealso::
425453
426-
`Clustering <https://redis.readthedocs.io/en/stable/clustering.html>`_
454+
`Clustering <https://redis.readthedocs.io/en/stable/clustering.html>`__
427455
in the redis-py documentation.
428456
429457
Requires redis-py version >=4.1.0.

dogpile/cache/backends/valkey.py

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Valkey Backends
33
------------------
44
5-
Provides backends for talking to `Valkey <http://valkey.io>`_.
5+
Provides backends for talking to `Valkey <http://valkey.io>`__.
66
77
"""
88

@@ -22,8 +22,8 @@
2222

2323

2424
class ValkeyBackend(BytesBackend):
25-
r"""A `Valkey <http://valkey.io/>`_ backend, using the
26-
`valkey-py <http://pypi.python.org/pypi/valkey/>`_ driver.
25+
r"""A `Valkey <http://valkey.io/>`__ backend, using the
26+
`valkey-py <http://pypi.python.org/pypi/valkey/>`__ driver.
2727
2828
.. versionadded:: 1.3.4
2929
@@ -73,6 +73,21 @@ class ValkeyBackend(BytesBackend):
7373
Valkey should expire it. This argument is only valid when
7474
``distributed_lock`` is ``True``.
7575
76+
:param lock_sleep: integer, number of seconds to sleep when failed to
77+
acquire a lock. This argument is only valid when
78+
``distributed_lock`` is ``True``.
79+
80+
:param lock_blocking: bool, default ``True``. Passed to the Valkey client's
81+
lock constructor when ``distributed_lock`` is ``True``.
82+
83+
.. versionadded:: 1.4.1
84+
85+
:param lock_blocking_timeout: int or float, default ``None``. Passed to
86+
the Valkey client's lock constructor, when ``distributed_lock`` is
87+
``True``.
88+
89+
.. versionadded:: 1.4.1
90+
7691
:param socket_timeout: float, seconds for socket timeout.
7792
Default is None (no timeout).
7893
@@ -85,10 +100,6 @@ class ValkeyBackend(BytesBackend):
85100
:param socket_keepalive_options: dict, socket keepalive options.
86101
Default is None (no options).
87102
88-
:param lock_sleep: integer, number of seconds to sleep when failed to
89-
acquire a lock. This argument is only valid when
90-
``distributed_lock`` is ``True``.
91-
92103
:param connection_pool: ``valkey.ConnectionPool`` object. If provided,
93104
this object supersedes other connection arguments passed to the
94105
``valkey.StrictValkey`` instance, including url and/or host as well as
@@ -100,13 +111,18 @@ class ValkeyBackend(BytesBackend):
100111
asynchronous runners, as they run in a different thread than the one
101112
used to create the lock.
102113
114+
:param ssl: boolean, default ``None``. If set, this is passed to the
115+
``valkey.StrictValkey`` constructor as ``ssl``. All additional ``ssl_``
116+
prefixed args should be submitted via the
117+
:paramref:`.ValkeyBackend.connection_kwargs` dict.
118+
119+
.. versionadded:: 1.4.1
120+
103121
:param connection_kwargs: dict, additional keyword arguments are passed
104122
along to the
105123
``StrictValkey.from_url()`` method or ``StrictValkey()`` constructor
106124
directly, including parameters like ``ssl``, ``ssl_certfile``,
107125
``charset``, etc.
108-
109-
110126
"""
111127

112128
def __init__(self, arguments):
@@ -118,7 +134,6 @@ def __init__(self, arguments):
118134
self.password = arguments.pop("password", None)
119135
self.port = arguments.pop("port", 6379)
120136
self.db = arguments.pop("db", 0)
121-
self.distributed_lock = arguments.pop("distributed_lock", False)
122137
self.socket_timeout = arguments.pop("socket_timeout", None)
123138
self.socket_connect_timeout = arguments.pop(
124139
"socket_connect_timeout", None
@@ -127,8 +142,19 @@ def __init__(self, arguments):
127142
self.socket_keepalive_options = arguments.pop(
128143
"socket_keepalive_options", None
129144
)
145+
146+
# additional ssl params should be submitted in `connection_kwargs`
147+
self.ssl = arguments.pop("ssl", None)
148+
149+
# used by `get_mutex`
150+
self.distributed_lock = arguments.pop("distributed_lock", False)
130151
self.lock_timeout = arguments.pop("lock_timeout", None)
131152
self.lock_sleep = arguments.pop("lock_sleep", 0.1)
153+
self.lock_blocking = arguments.pop("lock_blocking", True)
154+
self.lock_blocking_timeout = arguments.pop(
155+
"lock_blocking_timeout", None
156+
)
157+
132158
self.thread_local_lock = arguments.pop("thread_local_lock", True)
133159
self.connection_kwargs = arguments.pop("connection_kwargs", {})
134160

@@ -171,6 +197,8 @@ def _create_client(self):
171197
args["socket_keepalive_options"] = (
172198
self.socket_keepalive_options
173199
)
200+
if self.ssl is not None:
201+
args["ssl"] = self.ssl
174202

175203
if self.url is not None:
176204
args.update(url=self.url)
@@ -195,6 +223,8 @@ def get_mutex(self, key):
195223
timeout=self.lock_timeout,
196224
sleep=self.lock_sleep,
197225
thread_local=self.thread_local_lock,
226+
blocking=self.lock_blocking,
227+
blocking_timeout=self.lock_blocking_timeout,
198228
)
199229
)
200230
else:
@@ -251,10 +281,10 @@ def locked(self) -> bool:
251281

252282

253283
class ValkeySentinelBackend(ValkeyBackend):
254-
"""A `Valkey <http://valkey.io/>`_ backend, using the
255-
`valkey-py <http://pypi.python.org/pypi/valkey/>`_ driver.
284+
"""A `Valkey <http://valkey.io/>`__ backend, using the
285+
`valkey-py <http://pypi.python.org/pypi/valkey/>`__ driver.
256286
This backend is to be used when using
257-
`Valkey Sentinel <https://valkey.io/docs/management/sentinel/>`_.
287+
`Valkey Sentinel <https://valkey.io/docs/management/sentinel/>`__.
258288
259289
.. versionadded:: 1.0.0
260290
@@ -405,17 +435,17 @@ def _create_client(self):
405435

406436

407437
class ValkeyClusterBackend(ValkeyBackend):
408-
r"""A `Valkey <http://valkey.io/>`_ backend, using the
409-
`valkey-py <http://pypi.python.org/pypi/valkey/>`_ driver.
438+
r"""A `Valkey <http://valkey.io/>`__ backend, using the
439+
`valkey-py <http://pypi.python.org/pypi/valkey/>`__ driver.
410440
This backend is to be used when connecting to a
411-
`Valkey Cluster <https://valkey.io/docs/management/scaling/>`_ which
441+
`Valkey Cluster <https://valkey.io/docs/management/scaling/>`__ which
412442
will use the
413443
`ValkeyCluster Client
414-
<https://valkey.readthedocs.io/en/stable/connections.html#cluster-client>`_.
444+
<https://valkey.readthedocs.io/en/stable/connections.html#cluster-client>`__.
415445
416446
.. seealso::
417447
418-
`Clustering <https://valkey.readthedocs.io/en/stable/clustering.html>`_
448+
`Clustering <https://valkey.readthedocs.io/en/stable/clustering.html>`__
419449
in the valkey-py documentation.
420450
421451
Requires valkey-py version >=4.1.0.

0 commit comments

Comments
 (0)