Skip to content

Commit 0981f49

Browse files
authored
🎨Maintenance: make redis client use the client name to ease debugging (#6700)
1 parent f7e6d5b commit 0981f49

File tree

22 files changed

+86
-104
lines changed

22 files changed

+86
-104
lines changed

packages/service-library/src/servicelib/redis.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ async def _cancel_or_warn(task: Task) -> None:
6060
@dataclass
6161
class RedisClientSDK:
6262
redis_dsn: str
63+
client_name: str
6364
decode_responses: bool = _DEFAULT_DECODE_RESPONSES
6465
health_check_interval: datetime.timedelta = _DEFAULT_HEALTH_CHECK_INTERVAL
6566

@@ -86,7 +87,7 @@ def __post_init__(self):
8687
socket_connect_timeout=_DEFAULT_SOCKET_TIMEOUT.total_seconds(),
8788
encoding="utf-8",
8889
decode_responses=self.decode_responses,
89-
auto_close_connection_pool=True,
90+
client_name=self.client_name,
9091
)
9192

9293
@retry(**RedisRetryPolicyUponInitialization(_logger).kwargs)
@@ -238,6 +239,7 @@ class RedisClientsManager:
238239

239240
databases_configs: set[RedisManagerDBConfig]
240241
settings: RedisSettings
242+
client_name: str
241243

242244
_client_sdks: dict[RedisDatabase, RedisClientSDK] = field(default_factory=dict)
243245

@@ -247,6 +249,7 @@ async def setup(self) -> None:
247249
redis_dsn=self.settings.build_redis_dsn(config.database),
248250
decode_responses=config.decode_responses,
249251
health_check_interval=config.health_check_interval,
252+
client_name=f"{self.client_name}",
250253
)
251254

252255
for client in self._client_sdks.values():

packages/service-library/tests/conftest.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,12 @@ async def _(
8080
database: RedisDatabase, decode_response: bool = True # noqa: FBT002
8181
) -> AsyncIterator[RedisClientSDK]:
8282
redis_resources_dns = redis_service.build_redis_dsn(database)
83-
client = RedisClientSDK(redis_resources_dns, decode_responses=decode_response)
83+
client = RedisClientSDK(
84+
redis_resources_dns, decode_responses=decode_response, client_name="pytest"
85+
)
8486
assert client
8587
assert client.redis_dsn == redis_resources_dns
88+
assert client.client_name == "pytest"
8689
await client.setup()
8790

8891
yield client
@@ -94,7 +97,9 @@ async def _cleanup_redis_data(clients_manager: RedisClientsManager) -> None:
9497
await clients_manager.client(db).redis.flushall()
9598

9699
async with RedisClientsManager(
97-
{RedisManagerDBConfig(db) for db in RedisDatabase}, redis_service
100+
{RedisManagerDBConfig(db) for db in RedisDatabase},
101+
redis_service,
102+
client_name="pytest",
98103
) as clients_manager:
99104
await _cleanup_redis_data(clients_manager)
100105
yield _

packages/service-library/tests/deferred_tasks/example_app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def __init__(self, redis_settings: RedisSettings, port: int) -> None:
6060
self.redis: Redis = RedisClientSDK(
6161
redis_settings.build_redis_dsn(RedisDatabase.DEFERRED_TASKS),
6262
decode_responses=True,
63+
client_name="example_app",
6364
).redis
6465
self.port = port
6566

@@ -84,6 +85,7 @@ def __init__(
8485
self._redis_client = RedisClientSDK(
8586
redis_settings.build_redis_dsn(RedisDatabase.DEFERRED_TASKS),
8687
decode_responses=False,
88+
client_name="example_app",
8789
)
8890
self._manager = DeferredManager(
8991
rabbit_settings,

packages/service-library/tests/deferred_tasks/test__base_deferred_handler.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ async def redis_client_sdk(
5555
sdk = RedisClientSDK(
5656
redis_service.build_redis_dsn(RedisDatabase.DEFERRED_TASKS),
5757
decode_responses=False,
58+
client_name="pytest",
5859
)
5960
await sdk.setup()
6061
yield sdk

packages/service-library/tests/test_pools.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from asyncio import BaseEventLoop
1+
import asyncio
22
from concurrent.futures import ProcessPoolExecutor
33

44
from servicelib.pools import (
@@ -11,17 +11,25 @@ def return_int_one() -> int:
1111
return 1
1212

1313

14-
async def test_default_thread_pool_executor(event_loop: BaseEventLoop) -> None:
15-
assert await event_loop.run_in_executor(None, return_int_one) == 1
14+
async def test_default_thread_pool_executor() -> None:
15+
assert await asyncio.get_running_loop().run_in_executor(None, return_int_one) == 1
1616

1717

18-
async def test_blocking_process_pool_executor(event_loop: BaseEventLoop) -> None:
19-
assert await event_loop.run_in_executor(ProcessPoolExecutor(), return_int_one) == 1
18+
async def test_blocking_process_pool_executor() -> None:
19+
assert (
20+
await asyncio.get_running_loop().run_in_executor(
21+
ProcessPoolExecutor(), return_int_one
22+
)
23+
== 1
24+
)
2025

2126

22-
async def test_non_blocking_process_pool_executor(event_loop: BaseEventLoop) -> None:
27+
async def test_non_blocking_process_pool_executor() -> None:
2328
with non_blocking_process_pool_executor() as executor:
24-
assert await event_loop.run_in_executor(executor, return_int_one) == 1
29+
assert (
30+
await asyncio.get_running_loop().run_in_executor(executor, return_int_one)
31+
== 1
32+
)
2533

2634

2735
async def test_same_pool_instances() -> None:
@@ -36,9 +44,12 @@ async def test_different_pool_instances() -> None:
3644
assert first != second
3745

3846

39-
async def test_non_blocking_thread_pool_executor(event_loop: BaseEventLoop) -> None:
47+
async def test_non_blocking_thread_pool_executor() -> None:
4048
with non_blocking_thread_pool_executor() as executor:
41-
assert await event_loop.run_in_executor(executor, return_int_one) == 1
49+
assert (
50+
await asyncio.get_running_loop().run_in_executor(executor, return_int_one)
51+
== 1
52+
)
4253

4354

4455
async def test_same_thread_pool_instances() -> None:

packages/service-library/tests/test_redis.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,9 @@ async def test_redis_client_sdks_manager(
277277
RedisManagerDBConfig(db) for db in RedisDatabase
278278
}
279279
manager = RedisClientsManager(
280-
databases_configs=all_redis_configs, settings=redis_service
280+
databases_configs=all_redis_configs,
281+
settings=redis_service,
282+
client_name="pytest",
281283
)
282284

283285
async with manager:
@@ -290,7 +292,7 @@ async def test_redis_client_sdk_setup_shutdown(
290292
):
291293
# setup
292294
redis_resources_dns = redis_service.build_redis_dsn(RedisDatabase.RESOURCES)
293-
client = RedisClientSDK(redis_resources_dns)
295+
client = RedisClientSDK(redis_resources_dns, client_name="pytest")
294296
assert client
295297
assert client.redis_dsn == redis_resources_dns
296298

packages/service-library/tests/test_redis__recoonection.py renamed to packages/service-library/tests/test_redis__reconection.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ async def test_redis_client_sdk_lost_connection(
2121
docker_client: docker.client.DockerClient,
2222
):
2323
redis_client_sdk = RedisClientSDK(
24-
redis_service.build_redis_dsn(RedisDatabase.RESOURCES)
24+
redis_service.build_redis_dsn(RedisDatabase.RESOURCES), client_name="pytest"
2525
)
26-
26+
assert redis_client_sdk.client_name == "pytest"
2727
await redis_client_sdk.setup()
2828

2929
assert await redis_client_sdk.ping() is True
@@ -41,3 +41,5 @@ async def test_redis_client_sdk_lost_connection(
4141
):
4242
with attempt:
4343
assert await redis_client_sdk.ping() is False
44+
45+
await redis_client_sdk.shutdown()

packages/service-library/tests/test_utils.py

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import asyncio
66
from collections.abc import AsyncIterator, Awaitable, Coroutine, Iterator
77
from copy import copy, deepcopy
8-
from random import randint
98
from typing import NoReturn
109
from unittest import mock
1110

@@ -66,7 +65,6 @@ def mock_logger(mocker: MockerFixture) -> Iterator[mock.Mock]:
6665

6766

6867
async def test_logged_gather(
69-
event_loop: asyncio.AbstractEventLoop,
7068
coros: list[Coroutine],
7169
mock_logger: mock.Mock,
7270
):
@@ -79,7 +77,7 @@ async def test_logged_gather(
7977
# NOTE: only first error in the list is raised, since it is not RuntimeError, that task
8078
assert isinstance(excinfo.value, ValueError)
8179

82-
for task in asyncio.all_tasks(event_loop):
80+
for task in asyncio.all_tasks(asyncio.get_running_loop()):
8381
if task is not asyncio.current_task():
8482
# info
8583
task.print_stack()
@@ -148,7 +146,7 @@ async def test_fire_and_forget_1000s_tasks(faker: Faker):
148146
tasks_collection = set()
149147

150148
async def _some_task(n: int) -> str:
151-
await asyncio.sleep(randint(1, 3))
149+
await asyncio.sleep(faker.random_int(1, 3))
152150
return f"I'm great since I slept a bit, and by the way I'm task {n}"
153151

154152
for n in range(1000):
@@ -251,7 +249,6 @@ async def test_limited_gather_limits(
251249

252250

253251
async def test_limited_gather(
254-
event_loop: asyncio.AbstractEventLoop,
255252
coros: list[Coroutine],
256253
mock_logger: mock.Mock,
257254
):
@@ -266,7 +263,7 @@ async def test_limited_gather(
266263

267264
unfinished_tasks = [
268265
task
269-
for task in asyncio.all_tasks(event_loop)
266+
for task in asyncio.all_tasks(asyncio.get_running_loop())
270267
if task is not asyncio.current_task()
271268
]
272269
final_results = await asyncio.gather(*unfinished_tasks, return_exceptions=True)
@@ -288,9 +285,7 @@ async def test_limited_gather_wo_raising(
288285
assert results[5] == 5
289286

290287

291-
async def test_limited_gather_cancellation(
292-
event_loop: asyncio.AbstractEventLoop, slow_successful_coros_list: list[Coroutine]
293-
):
288+
async def test_limited_gather_cancellation(slow_successful_coros_list: list[Coroutine]):
294289
task = asyncio.create_task(limited_gather(*slow_successful_coros_list, limit=0))
295290
await asyncio.sleep(3)
296291
task.cancel()
@@ -300,7 +295,7 @@ async def test_limited_gather_cancellation(
300295
# check all coros are cancelled
301296
unfinished_tasks = [
302297
task
303-
for task in asyncio.all_tasks(event_loop)
298+
for task in asyncio.all_tasks(asyncio.get_running_loop())
304299
if task is not asyncio.current_task()
305300
]
306301
assert not unfinished_tasks

services/autoscaling/src/simcore_service_autoscaling/modules/redis.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from servicelib.redis import RedisClientSDK
66
from settings_library.redis import RedisDatabase, RedisSettings
77

8+
from .._meta import APP_NAME
9+
810
logger = logging.getLogger(__name__)
911

1012

@@ -13,7 +15,9 @@ async def on_startup() -> None:
1315
app.state.redis_client_sdk = None
1416
settings: RedisSettings = app.state.settings.AUTOSCALING_REDIS
1517
redis_locks_dsn = settings.build_redis_dsn(RedisDatabase.LOCKS)
16-
app.state.redis_client_sdk = client = RedisClientSDK(redis_locks_dsn)
18+
app.state.redis_client_sdk = client = RedisClientSDK(
19+
redis_locks_dsn, client_name=APP_NAME
20+
)
1721
await client.setup()
1822

1923
async def on_shutdown() -> None:

services/clusters-keeper/src/simcore_service_clusters_keeper/modules/clusters_management_task.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from servicelib.background_task import start_periodic_task, stop_periodic_task
77
from servicelib.redis_utils import exclusive
88

9+
from .._meta import APP_NAME
910
from ..core.settings import ApplicationSettings
1011
from ..modules.redis import get_redis_client
1112
from .clusters_management_core import check_clusters
@@ -19,7 +20,7 @@ def on_app_startup(app: FastAPI) -> Callable[[], Awaitable[None]]:
1920
async def _startup() -> None:
2021
app_settings: ApplicationSettings = app.state.settings
2122

22-
lock_key = f"{app.title}:clusters-management_lock"
23+
lock_key = f"{APP_NAME}:clusters-management_lock"
2324
lock_value = json.dumps({})
2425
app.state.clusters_cleaning_task = start_periodic_task(
2526
exclusive(get_redis_client(app), lock_key=lock_key, lock_value=lock_value)(

0 commit comments

Comments
 (0)