Skip to content

Commit 844a635

Browse files
authored
Merge pull request #70 from valkey-io/aiven-sal/rp_import
Import some changes from redis-py: * Fix socket_timeout init * Add missing type hints for `retry.py` * Add details to the asyncio connection error message * Format connection errors in the same way everywhere * Drop unused dev-dep urllib3 * Close Unix sockets if the connection attempt fails * Cluster performance improvements * Bump version deps * Fix checking of module versions * Avoid dangling sockets in case of SSL handshake failure * Get rid of event_loop warnings * Resolve some docs warnings * Ensure safe defaults for TLS
2 parents 92e3d34 + 30cc14c commit 844a635

22 files changed

+278
-173
lines changed

.github/wordlist.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,4 @@ valkeymodules
159159
virtualenv
160160
www
161161
md
162+
yaml

dev_requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pytest-asyncio
1212
pytest-cov
1313
pytest-timeout
1414
ujson>=4.2.0
15-
urllib3<2
1615
uvloop
1716
vulture>=2.3.0
1817
wheel>=0.30.0

docs/conf.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@
128128
# further. For a list of options available for each theme, see the
129129
# documentation.
130130
html_theme_options = {
131-
"display_version": True,
132131
"footer_icons": [
133132
{
134133
"name": "GitHub",

docs/connections.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ ClusterNode
5555
Async Client
5656
************
5757

58-
See complete example: `here <examples/asyncio_examples.html>`_
58+
See complete example: `here <examples/asyncio_examples.html>`__
5959

6060
This client is used for communicating with Valkey, asynchronously.
6161

@@ -88,7 +88,7 @@ ClusterPipeline (Async)
8888
Connection
8989
**********
9090

91-
See complete example: `here <examples/connection_examples.html>`_
91+
See complete example: `here <examples/connection_examples.html>`__
9292

9393
Connection
9494
==========
@@ -104,7 +104,7 @@ Connection (Async)
104104
Connection Pools
105105
****************
106106

107-
See complete example: `here <examples/connection_examples.html>`_
107+
See complete example: `here <examples/connection_examples.html>`__
108108

109109
ConnectionPool
110110
==============

docs/opentelemetry.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Integrating OpenTelemetry
44
What is OpenTelemetry?
55
----------------------
66

7-
`OpenTelemetry <https://opentelemetry.io>`_ is an open-source observability framework for traces, metrics, and logs. It is a merger of OpenCensus and OpenTracing projects hosted by Cloud Native Computing Foundation.
7+
`OpenTelemetry <https://opentelemetry.io>`__ is an open-source observability framework for traces, metrics, and logs. It is a merger of OpenCensus and OpenTracing projects hosted by Cloud Native Computing Foundation.
88

99
OpenTelemetry allows developers to collect and export telemetry data in a vendor agnostic way. With OpenTelemetry, you can instrument your application once and then add or change vendors without changing the instrumentation, for example, here is a list of `popular DataDog competitors <https://uptrace.dev/get/compare/datadog-competitors.html>`_ that support OpenTelemetry.
1010

@@ -61,7 +61,7 @@ Once the code is patched, you can use valkey-py as usually:
6161
OpenTelemetry API
6262
-----------------
6363

64-
`OpenTelemetry <https://uptrace.dev/opentelemetry/>`_ API is a programming interface that you can use to instrument code and collect telemetry data such as traces, metrics, and logs.
64+
`OpenTelemetry API <https://uptrace.dev/opentelemetry/>`__ is a programming interface that you can use to instrument code and collect telemetry data such as traces, metrics, and logs.
6565

6666
You can use OpenTelemetry API to measure important operations:
6767

@@ -125,7 +125,7 @@ Alerting and notifications
125125

126126
Uptrace also allows you to monitor `OpenTelemetry metrics <https://uptrace.dev/opentelemetry/metrics.html>`_ using alerting rules. For example, the following monitor uses the group by node expression to create an alert whenever an individual Valkey shard is down:
127127

128-
.. code-block:: python
128+
.. code-block:: yaml
129129
130130
monitors:
131131
- name: Valkey shard is down
@@ -142,7 +142,7 @@ Uptrace also allows you to monitor `OpenTelemetry metrics <https://uptrace.dev/o
142142
143143
You can also create queries with more complex expressions. For example, the following rule creates an alert when the keyspace hit rate is lower than 75%:
144144

145-
.. code-block:: python
145+
.. code-block:: yaml
146146
147147
monitors:
148148
- name: Valkey read hit rate < 75%

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
async-timeout>=4.0.2
1+
async-timeout>=4.0.3

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
],
5858
extras_require={
5959
"libvalkey": ["libvalkey>=4.0.0b1"],
60-
"ocsp": ["cryptography>=36.0.1", "pyopenssl==20.0.1", "requests>=2.26.0"],
60+
"ocsp": ["cryptography>=36.0.1", "pyopenssl==23.2.1", "requests>=2.31.0"],
6161
},
6262
)

tests/conftest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,9 @@ def skip_ifmodversion_lt(min_version: str, module_name: str):
233233
for j in modules:
234234
if module_name == j.get("name"):
235235
version = j.get("ver")
236-
mv = int(min_version.replace(".", ""))
236+
mv = int(
237+
"".join(["%02d" % int(segment) for segment in min_version.split(".")])
238+
)
237239
check = version < mv
238240
return pytest.mark.skipif(check, reason="Valkey module version")
239241

tests/test_asyncio/test_connection.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
parse_url,
1515
)
1616
from valkey.asyncio import ConnectionPool, Valkey
17-
from valkey.asyncio.connection import Connection, UnixDomainSocketConnection
17+
from valkey.asyncio.connection import (
18+
Connection,
19+
SSLConnection,
20+
UnixDomainSocketConnection,
21+
)
1822
from valkey.asyncio.retry import Retry
1923
from valkey.backoff import NoBackoff
2024
from valkey.exceptions import ConnectionError, InvalidResponse, TimeoutError
@@ -494,3 +498,53 @@ async def test_connection_garbage_collection(request):
494498

495499
await client.aclose()
496500
await pool.aclose()
501+
502+
503+
@pytest.mark.parametrize(
504+
"conn, error, expected_message",
505+
[
506+
(SSLConnection(), OSError(), "Error connecting to localhost:6379."),
507+
(SSLConnection(), OSError(12), "Error 12 connecting to localhost:6379."),
508+
(
509+
SSLConnection(),
510+
OSError(12, "Some Error"),
511+
"Error 12 connecting to localhost:6379. Some Error.",
512+
),
513+
(
514+
UnixDomainSocketConnection(path="unix:///tmp/valkey.sock"),
515+
OSError(),
516+
"Error connecting to unix:///tmp/valkey.sock.",
517+
),
518+
(
519+
UnixDomainSocketConnection(path="unix:///tmp/valkey.sock"),
520+
OSError(12),
521+
"Error 12 connecting to unix:///tmp/valkey.sock.",
522+
),
523+
(
524+
UnixDomainSocketConnection(path="unix:///tmp/valkey.sock"),
525+
OSError(12, "Some Error"),
526+
"Error 12 connecting to unix:///tmp/valkey.sock. Some Error.",
527+
),
528+
],
529+
)
530+
async def test_format_error_message(conn, error, expected_message):
531+
"""Test that the _error_message function formats errors correctly"""
532+
error_message = conn._error_message(error)
533+
assert error_message == expected_message
534+
535+
536+
async def test_network_connection_failure():
537+
with pytest.raises(ConnectionError) as e:
538+
valkey = Valkey(host="127.0.0.1", port=9999)
539+
await valkey.set("a", "b")
540+
assert str(e.value).startswith("Error 111 connecting to 127.0.0.1:9999. Connect")
541+
542+
543+
async def test_unix_socket_connection_failure():
544+
with pytest.raises(ConnectionError) as e:
545+
valkey = Valkey(unix_socket_path="unix:///tmp/a.sock")
546+
await valkey.set("a", "b")
547+
assert (
548+
str(e.value)
549+
== "Error 2 connecting to unix:///tmp/a.sock. No such file or directory."
550+
)

tests/test_asyncio/test_lock.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,16 +104,16 @@ async def test_blocking(self, r):
104104
lock_2 = self.get_lock(r, "foo")
105105
assert lock_2.blocking
106106

107-
async def test_blocking_timeout(self, r, event_loop):
107+
async def test_blocking_timeout(self, r):
108108
lock1 = self.get_lock(r, "foo")
109109
assert await lock1.acquire(blocking=False)
110110
bt = 0.2
111111
sleep = 0.05
112112
lock2 = self.get_lock(r, "foo", sleep=sleep, blocking_timeout=bt)
113-
start = event_loop.time()
113+
start = asyncio.get_running_loop().time()
114114
assert not await lock2.acquire()
115115
# The elapsed duration should be less than the total blocking_timeout
116-
assert bt >= (event_loop.time() - start) > bt - sleep
116+
assert bt >= (asyncio.get_running_loop().time() - start) > bt - sleep
117117
await lock1.release()
118118

119119
async def test_context_manager(self, r):

0 commit comments

Comments
 (0)