|
6 | 6 | import pytest
|
7 | 7 |
|
8 | 8 | import redis
|
| 9 | +from redis.asyncio import Redis |
9 | 10 | from redis.asyncio.connection import (
|
10 | 11 | BaseParser,
|
11 | 12 | Connection,
|
@@ -41,6 +42,50 @@ async def test_invalid_response(create_redis):
|
41 | 42 | await r.connection.disconnect()
|
42 | 43 |
|
43 | 44 |
|
| 45 | +@pytest.mark.onlynoncluster |
| 46 | +async def test_single_connection(): |
| 47 | + """Test that concurrent requests on a single client are synchronised.""" |
| 48 | + r = Redis(single_connection_client=True) |
| 49 | + |
| 50 | + init_call_count = 0 |
| 51 | + command_call_count = 0 |
| 52 | + in_use = False |
| 53 | + |
| 54 | + class Retry_: |
| 55 | + async def call_with_retry(self, _, __): |
| 56 | + # If we remove the single-client lock, this error gets raised as two |
| 57 | + # coroutines will be vying for the `in_use` flag due to the two |
| 58 | + # asymmetric sleep calls |
| 59 | + nonlocal command_call_count |
| 60 | + nonlocal in_use |
| 61 | + if in_use is True: |
| 62 | + raise ValueError("Commands should be executed one at a time.") |
| 63 | + in_use = True |
| 64 | + await asyncio.sleep(0.01) |
| 65 | + command_call_count += 1 |
| 66 | + await asyncio.sleep(0.03) |
| 67 | + in_use = False |
| 68 | + return "foo" |
| 69 | + |
| 70 | + mock_conn = mock.MagicMock() |
| 71 | + mock_conn.retry = Retry_() |
| 72 | + |
| 73 | + async def get_conn(_): |
| 74 | + # Validate only one client is created in single-client mode when |
| 75 | + # concurrent requests are made |
| 76 | + nonlocal init_call_count |
| 77 | + await asyncio.sleep(0.01) |
| 78 | + init_call_count += 1 |
| 79 | + return mock_conn |
| 80 | + |
| 81 | + with mock.patch.object(r.connection_pool, "get_connection", get_conn): |
| 82 | + with mock.patch.object(r.connection_pool, "release"): |
| 83 | + await asyncio.gather(r.set("a", "b"), r.set("c", "d")) |
| 84 | + |
| 85 | + assert init_call_count == 1 |
| 86 | + assert command_call_count == 2 |
| 87 | + |
| 88 | + |
44 | 89 | @skip_if_server_version_lt("4.0.0")
|
45 | 90 | @pytest.mark.redismod
|
46 | 91 | @pytest.mark.onlynoncluster
|
|
0 commit comments