Skip to content

Commit

Permalink
Project improvements (#25)
Browse files Browse the repository at this point in the history
* migrate from setup.cfg to pyproject.toml; remove mock dependency

* use asyncio.timeout instead of async_timeout package for python 3.11; fix aioredis tests

* CI: add py3.12

* add py3.12 to project classifiers

---------

Co-authored-by: Anton Ilyushenkov <[email protected]>
  • Loading branch information
DriverX and Anton Ilyushenkov authored Nov 28, 2023
1 parent 9fb19d9 commit c293324
Show file tree
Hide file tree
Showing 28 changed files with 263 additions and 238 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
- '3.9'
- '3.10'
- '3.11'
- '3.12'
with_aioredis:
- 'yes'
- 'no'
Expand Down
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Changes
------------------

* fix stuck `aioredis.Connection` socket reader routine for sharded PUB/SUB when cluster reshard and Redis starts respond `MOVED` error on `SSUBSCRIBE` commands [#24](https://github.com/DriverX/aioredis-cluster/pull/24)

2.5.0 (2023-04-03)
------------------

Expand Down
6 changes: 3 additions & 3 deletions dev/test_pool_recovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from collections import deque
from typing import Deque, Optional

import async_timeout
from aioredis import Redis, create_pool

from aioredis_cluster.compat.asyncio import timeout
from aioredis_cluster.pool import ConnectionsPool

logger = logging.getLogger(__name__)
Expand All @@ -26,7 +26,7 @@ async def routine(routine_id: int, redis: Redis) -> None:
count: Optional[int] = None
while True:
try:
async with async_timeout.timeout(5.0):
async with timeout(5.0):
with await redis as redis_conn:
count = await redis_conn.incr("counter")
local_count += 1
Expand Down Expand Up @@ -61,7 +61,7 @@ async def conn_acquirer(acquirer_id: int, redis: Redis):
count = 0
while True:
try:
async with async_timeout.timeout(None):
async with timeout(None):
with await redis as redis_conn:
count += 1
logger.info("%d: %d acquired conn", acquirer_id, count)
Expand Down
98 changes: 97 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,82 @@
[build-system]
requires = ["setuptools", "wheel"]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "aioredis-cluster"
description = "Redis Cluster support extension for aioredis"
authors = [
{name = "Anton Ilyushenkov", email = "[email protected]"},
]
maintainers = [
{name = "Anton Ilyushenkov", email = "[email protected]"},
]
classifiers = [
"License :: OSI Approved :: MIT License",
"Development Status :: 5 - Production/Stable",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3 :: Only",
"Operating System :: POSIX",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"Topic :: Software Development",
"Topic :: Software Development :: Libraries",
"Framework :: AsyncIO",
]
keywords = ["redis", "aioredis", "redis cluster", "asyncio"]
requires-python = ">=3.8"
dependencies = [
'async-timeout; python_version < "3.11"',
"hiredis < 3.0.0; platform_python_implementation == 'CPython'"
]
dynamic = ["version", "readme"]

[project.urls]
Repository = "https://github.com/DriverX/aioredis-cluster"

[project.optional-dependencies]
devel = [
"flake8",
"flake8-pyproject",
"mypy",
"isort",
"black==23.7.0",
"coverage",
"cython",
"pytest",
"pytest-cov",
"pytest-mock",
"pytest-asyncio>=0.21, <1.0",
"pytest-cov",
"pytest-xdist",
]
aioredis = [
"aioredis >=1.1.0, <1.4.0; python_version < '3.10'",
]

[tool.setuptools]
zip-safe = false
include-package-data = true
platforms = ["POSIX"]
license-files = ["LICENSE"]

[tool.setuptools.dynamic]
version = {attr = "aioredis_cluster._version.__version__"}
readme = {file = ["README.md", "CHANGES.md", "CONTRIBUTORS.md"], content-type = "text/markdown"}

[tool.setuptools.packages.find]
where = ["src"]
include = [
"aioredis_cluster",
"aioredis_cluster.*",
]

[tool.isort]
profile = "black"
known_first_party = ["aioredis_cluster"]
Expand All @@ -11,3 +86,24 @@ known_third_party = ["aioredis"]
line-length = 100
target-version = ["py38"]
exclude = '.pyi$'

[tool.pytest.ini_options]
addopts = "--cov-report=term --cov-report=html -v"
asyncio_mode = "auto"

[tool.coverage.run]
branch = true
source = ["src"]

[tool.flake8]
max-line-length = 100
extend-ignore = ["W606", "E203", "E741"]

[tool.mypy]
ignore_missing_imports = true
check_untyped_defs = true
no_implicit_optional = false

[[tool.mypy.overrides]]
module = "aioredis_cluster._aioredis.*"
ignore_errors = true
87 changes: 0 additions & 87 deletions setup.cfg

This file was deleted.

30 changes: 16 additions & 14 deletions src/aioredis_cluster/_aioredis/sentinel/pool.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import asyncio
import contextlib
from concurrent.futures import ALL_COMPLETED

from async_timeout import timeout as async_timeout
from aioredis_cluster.compat.asyncio import timeout as atimeout

from ..errors import (
MasterNotFoundError,
Expand Down Expand Up @@ -263,7 +262,7 @@ async def _connect_sentinel(self, address, timeout, pools):
connections pool or exception.
"""
try:
with async_timeout(timeout):
async with atimeout(timeout):
pool = await create_pool(
address,
minsize=1,
Expand Down Expand Up @@ -296,16 +295,17 @@ async def discover_master(self, service, timeout):
pools = self._pools[:]
for sentinel in pools:
try:
with async_timeout(timeout):
async with atimeout(timeout):
address = await self._get_masters_address(sentinel, service)

pool = self._masters[service]
with async_timeout(timeout), contextlib.ExitStack() as stack:
async with atimeout(timeout):
conn = await pool._create_new_connection(address)
stack.callback(conn.close)
await self._verify_service_role(conn, "master")
stack.pop_all()

try:
await self._verify_service_role(conn, "master")
except BaseException:
conn.close()
raise
return conn
except asyncio.CancelledError:
# we must correctly handle CancelledError(s):
Expand Down Expand Up @@ -335,14 +335,16 @@ async def discover_slave(self, service, timeout, **kwargs):
pools = self._pools[:]
for sentinel in pools:
try:
with async_timeout(timeout):
async with atimeout(timeout):
address = await self._get_slave_address(sentinel, service) # add **kwargs
pool = self._slaves[service]
with async_timeout(timeout), contextlib.ExitStack() as stack:
async with atimeout(timeout):
conn = await pool._create_new_connection(address)
stack.callback(conn.close)
await self._verify_service_role(conn, "slave")
stack.pop_all()
try:
await self._verify_service_role(conn, "slave")
except BaseException:
conn.close()
raise
return conn
except asyncio.CancelledError:
raise
Expand Down
2 changes: 1 addition & 1 deletion src/aioredis_cluster/aioredis/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import ssl
from typing import Awaitable, Callable, List, Optional, Tuple, Type, Union

from async_timeout import timeout as atimeout
from aioredis_cluster.compat.asyncio import timeout as atimeout

from .abc import AbcConnection
from .util import parse_url
Expand Down
3 changes: 1 addition & 2 deletions src/aioredis_cluster/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
Union,
)

from async_timeout import timeout as atimeout

from aioredis_cluster.abc import AbcChannel, AbcCluster, AbcPool
from aioredis_cluster.aioredis import Redis, create_pool
from aioredis_cluster.aioredis.errors import (
Expand All @@ -30,6 +28,7 @@
from aioredis_cluster.command_exec import ExecuteContext, ExecuteFailProps, ExecuteProps
from aioredis_cluster.command_info import CommandInfo, extract_keys
from aioredis_cluster.commands import RedisCluster
from aioredis_cluster.compat.asyncio import timeout as atimeout
from aioredis_cluster.crc import key_slot
from aioredis_cluster.errors import (
AskError,
Expand Down
Empty file.
17 changes: 17 additions & 0 deletions src/aioredis_cluster/compat/asyncio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import asyncio

try:
from async_timeout import timeout as _async_timeout
except ImportError:
_async_timeout = None # type: ignore


__all__ = ("timeout",)


if hasattr(asyncio, "timeout"):
timeout = asyncio.timeout
elif _async_timeout is not None:
timeout = _async_timeout
else:
raise RuntimeError("async timeout compat version not found")
Loading

0 comments on commit c293324

Please sign in to comment.