redis 7.0.0b1__tar.gz → 7.0.0b3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {redis-7.0.0b1 → redis-7.0.0b3}/PKG-INFO +3 -1
- {redis-7.0.0b1 → redis-7.0.0b3}/dev_requirements.txt +1 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/pyproject.toml +9 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/__init__.py +1 -1
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/base.py +36 -22
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/client.py +20 -6
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/cluster.py +11 -2
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/connection.py +61 -1
- redis-7.0.0b3/redis/asyncio/http/http_client.py +265 -0
- redis-7.0.0b3/redis/asyncio/multidb/client.py +528 -0
- redis-7.0.0b3/redis/asyncio/multidb/command_executor.py +339 -0
- redis-7.0.0b3/redis/asyncio/multidb/config.py +210 -0
- redis-7.0.0b3/redis/asyncio/multidb/database.py +69 -0
- redis-7.0.0b3/redis/asyncio/multidb/event.py +84 -0
- redis-7.0.0b3/redis/asyncio/multidb/failover.py +125 -0
- redis-7.0.0b3/redis/asyncio/multidb/failure_detector.py +38 -0
- redis-7.0.0b3/redis/asyncio/multidb/healthcheck.py +292 -0
- redis-7.0.0b3/redis/background.py +204 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/client.py +41 -18
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/cluster.py +5 -1
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/core.py +10 -3
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/connection.py +206 -151
- redis-7.0.0b3/redis/data_structure.py +81 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/event.py +84 -10
- redis-7.0.0b3/redis/http/http_client.py +425 -0
- redis-7.0.0b1/redis/maintenance_events.py → redis-7.0.0b3/redis/maint_notifications.py +154 -140
- redis-7.0.0b3/redis/multidb/circuit.py +144 -0
- redis-7.0.0b3/redis/multidb/client.py +524 -0
- redis-7.0.0b3/redis/multidb/command_executor.py +350 -0
- redis-7.0.0b3/redis/multidb/config.py +207 -0
- redis-7.0.0b3/redis/multidb/database.py +130 -0
- redis-7.0.0b3/redis/multidb/event.py +89 -0
- redis-7.0.0b3/redis/multidb/exception.py +17 -0
- redis-7.0.0b3/redis/multidb/failover.py +125 -0
- redis-7.0.0b3/redis/multidb/failure_detector.py +104 -0
- redis-7.0.0b3/redis/multidb/healthcheck.py +289 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/retry.py +14 -1
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/utils.py +14 -0
- redis-7.0.0b3/tests/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/conftest.py +7 -0
- redis-7.0.0b3/tests/test_asyncio/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_commands.py +23 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_connection_pool.py +3 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/__init__.py +0 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/conftest.py +131 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/test_client.py +628 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/test_command_executor.py +181 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/test_config.py +166 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/test_failover.py +169 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/test_failure_detector.py +128 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/test_healthcheck.py +401 -0
- redis-7.0.0b3/tests/test_asyncio/test_multidb/test_pipeline.py +488 -0
- redis-7.0.0b3/tests/test_asyncio/test_scenario/__init__.py +0 -0
- redis-7.0.0b3/tests/test_asyncio/test_scenario/conftest.py +116 -0
- redis-7.0.0b3/tests/test_asyncio/test_scenario/test_active_active.py +420 -0
- redis-7.0.0b3/tests/test_asyncio/test_ssl.py +143 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_vsets.py +2 -2
- redis-7.0.0b3/tests/test_auth/__init__.py +0 -0
- redis-7.0.0b3/tests/test_background.py +94 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_commands.py +51 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_connection_pool.py +62 -2
- redis-7.0.0b3/tests/test_data_structure.py +94 -0
- redis-7.0.0b3/tests/test_event.py +67 -0
- redis-7.0.0b3/tests/test_http/__init__.py +0 -0
- redis-7.0.0b3/tests/test_http/test_http_client.py +371 -0
- redis-7.0.0b3/tests/test_maint_notifications.py +893 -0
- redis-7.0.0b1/tests/test_maintenance_events_handling.py → redis-7.0.0b3/tests/test_maint_notifications_handling.py +379 -325
- redis-7.0.0b3/tests/test_multidb/__init__.py +0 -0
- redis-7.0.0b3/tests/test_multidb/conftest.py +131 -0
- redis-7.0.0b3/tests/test_multidb/test_circuit.py +57 -0
- redis-7.0.0b3/tests/test_multidb/test_client.py +615 -0
- redis-7.0.0b3/tests/test_multidb/test_command_executor.py +173 -0
- redis-7.0.0b3/tests/test_multidb/test_config.py +161 -0
- redis-7.0.0b3/tests/test_multidb/test_failover.py +161 -0
- redis-7.0.0b3/tests/test_multidb/test_failure_detector.py +117 -0
- redis-7.0.0b3/tests/test_multidb/test_healthcheck.py +385 -0
- redis-7.0.0b3/tests/test_multidb/test_pipeline.py +489 -0
- redis-7.0.0b3/tests/test_scenario/__init__.py +0 -0
- redis-7.0.0b3/tests/test_scenario/conftest.py +241 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_scenario/fault_injector_client.py +3 -2
- redis-7.0.0b1/tests/test_scenario/hitless_upgrade_helpers.py → redis-7.0.0b3/tests/test_scenario/maint_notifications_helpers.py +68 -14
- redis-7.0.0b3/tests/test_scenario/test_active_active.py +460 -0
- redis-7.0.0b1/tests/test_scenario/test_hitless_upgrade.py → redis-7.0.0b3/tests/test_scenario/test_maint_notifications.py +393 -92
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_ssl.py +97 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_vsets.py +2 -2
- redis-7.0.0b1/tests/test_asyncio/test_ssl.py +0 -56
- redis-7.0.0b1/tests/test_maintenance_events.py +0 -869
- redis-7.0.0b1/tests/test_scenario/conftest.py +0 -120
- {redis-7.0.0b1 → redis-7.0.0b3}/.gitignore +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/LICENSE +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/README.md +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/commands.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/encoders.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/helpers.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/hiredis.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/resp2.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/resp3.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/_parsers/socket.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/__init__.py +0 -0
- {redis-7.0.0b1/redis/auth → redis-7.0.0b3/redis/asyncio/http}/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/lock.py +0 -0
- {redis-7.0.0b1/tests → redis-7.0.0b3/redis/asyncio/multidb}/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/retry.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/sentinel.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/asyncio/utils.py +0 -0
- {redis-7.0.0b1/tests/test_asyncio → redis-7.0.0b3/redis/auth}/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/auth/err.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/auth/idp.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/auth/token.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/auth/token_manager.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/backoff.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/cache.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/bf/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/bf/commands.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/bf/info.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/cluster.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/helpers.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/json/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/json/_util.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/json/commands.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/json/decoders.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/json/path.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/redismodules.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/_util.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/aggregation.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/commands.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/dialect.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/document.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/field.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/index_definition.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/profile_information.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/query.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/querystring.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/reducers.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/result.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/search/suggestion.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/sentinel.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/timeseries/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/timeseries/commands.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/timeseries/info.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/timeseries/utils.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/vectorset/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/vectorset/commands.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/commands/vectorset/utils.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/crc.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/credentials.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/exceptions.py +0 -0
- {redis-7.0.0b1/tests/test_auth → redis-7.0.0b3/redis/http}/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/lock.py +0 -0
- {redis-7.0.0b1/tests/test_scenario → redis-7.0.0b3/redis/multidb}/__init__.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/ocsp.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/py.typed +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/sentinel.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/redis/typing.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/entraid_utils.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/mocks.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/ssl_utils.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/compat.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/conftest.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/mocks.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_bloom.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_cluster.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_cluster_transaction.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_connect.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_connection.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_credentials.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_cwe_404.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_encoding.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_hash.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_json.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_lock.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_monitor.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_pipeline.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_pubsub.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_retry.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_scripting.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_search.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_sentinel.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_sentinel_managed_connection.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_timeseries.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_usage_counter.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/test_utils.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/testdata/jsontestdata.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/testdata/titles.csv +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_asyncio/testdata/will_play_text.csv.bz2 +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_auth/test_token.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_auth/test_token_manager.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_backoff.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_bloom.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_cache.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_cluster.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_cluster_transaction.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_command_parser.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_connect.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_connection.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_credentials.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_encoding.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_function.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_hash.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_helpers.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_json.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_lock.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_max_connections_error.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_monitor.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_multiprocessing.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_parsers/test_helpers.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_pipeline.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_pubsub.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_retry.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_scripting.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_search.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_sentinel.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_sentinel_managed_connection.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_timeseries.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/test_utils.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/testdata/jsontestdata.py +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/testdata/titles.csv +0 -0
- {redis-7.0.0b1 → redis-7.0.0b3}/tests/testdata/will_play_text.csv.bz2 +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redis
|
|
3
|
-
Version: 7.0.
|
|
3
|
+
Version: 7.0.0b3
|
|
4
4
|
Summary: Python client for Redis database and key-value store
|
|
5
5
|
Project-URL: Changes, https://github.com/redis/redis-py/releases
|
|
6
6
|
Project-URL: Code, https://github.com/redis/redis-py
|
|
@@ -28,6 +28,8 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
|
28
28
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
29
29
|
Requires-Python: >=3.9
|
|
30
30
|
Requires-Dist: async-timeout>=4.0.3; python_full_version < '3.11.3'
|
|
31
|
+
Provides-Extra: circuit-breaker
|
|
32
|
+
Requires-Dist: pybreaker>=1.4.0; extra == 'circuit-breaker'
|
|
31
33
|
Provides-Extra: hiredis
|
|
32
34
|
Requires-Dist: hiredis>=3.2.0; extra == 'hiredis'
|
|
33
35
|
Provides-Extra: jwt
|
|
@@ -42,6 +42,9 @@ ocsp = [
|
|
|
42
42
|
jwt = [
|
|
43
43
|
"PyJWT>=2.9.0",
|
|
44
44
|
]
|
|
45
|
+
circuit_breaker = [
|
|
46
|
+
"pybreaker>=1.4.0"
|
|
47
|
+
]
|
|
45
48
|
|
|
46
49
|
[project.urls]
|
|
47
50
|
Changes = "https://github.com/redis/redis-py/releases"
|
|
@@ -80,6 +83,12 @@ filterwarnings = [
|
|
|
80
83
|
# Ignore a coverage warning when COVERAGE_CORE=sysmon for Pythons < 3.12.
|
|
81
84
|
"ignore:sys.monitoring isn't available:coverage.exceptions.CoverageWarning",
|
|
82
85
|
]
|
|
86
|
+
log_cli_level = "INFO"
|
|
87
|
+
log_cli_date_format = "%H:%M:%S:%f"
|
|
88
|
+
log_cli = false
|
|
89
|
+
log_cli_format = "%(asctime)s %(levelname)s %(threadName)s: %(message)s"
|
|
90
|
+
log_level = "INFO"
|
|
91
|
+
capture = "yes"
|
|
83
92
|
|
|
84
93
|
[tool.ruff]
|
|
85
94
|
target-version = "py39"
|
|
@@ -4,13 +4,13 @@ from abc import ABC
|
|
|
4
4
|
from asyncio import IncompleteReadError, StreamReader, TimeoutError
|
|
5
5
|
from typing import Awaitable, Callable, List, Optional, Protocol, Union
|
|
6
6
|
|
|
7
|
-
from redis.
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
from redis.maint_notifications import (
|
|
8
|
+
MaintenanceNotification,
|
|
9
|
+
NodeFailedOverNotification,
|
|
10
|
+
NodeFailingOverNotification,
|
|
11
|
+
NodeMigratedNotification,
|
|
12
|
+
NodeMigratingNotification,
|
|
13
|
+
NodeMovingNotification,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
if sys.version_info.major >= 3 and sys.version_info.minor >= 11:
|
|
@@ -175,14 +175,14 @@ class MaintenanceNotificationsParser:
|
|
|
175
175
|
|
|
176
176
|
@staticmethod
|
|
177
177
|
def parse_maintenance_start_msg(response, notification_type):
|
|
178
|
-
# Expected message format is: <
|
|
178
|
+
# Expected message format is: <notification_type> <seq_number> <time>
|
|
179
179
|
id = response[1]
|
|
180
180
|
ttl = response[2]
|
|
181
181
|
return notification_type(id, ttl)
|
|
182
182
|
|
|
183
183
|
@staticmethod
|
|
184
184
|
def parse_maintenance_completed_msg(response, notification_type):
|
|
185
|
-
# Expected message format is: <
|
|
185
|
+
# Expected message format is: <notification_type> <seq_number>
|
|
186
186
|
id = response[1]
|
|
187
187
|
return notification_type(id)
|
|
188
188
|
|
|
@@ -200,7 +200,7 @@ class MaintenanceNotificationsParser:
|
|
|
200
200
|
host, port = value.split(":")
|
|
201
201
|
port = int(port) if port is not None else None
|
|
202
202
|
|
|
203
|
-
return
|
|
203
|
+
return NodeMovingNotification(id, host, port, ttl)
|
|
204
204
|
|
|
205
205
|
|
|
206
206
|
_INVALIDATION_MESSAGE = "invalidate"
|
|
@@ -217,25 +217,27 @@ _MAINTENANCE_MESSAGES = (
|
|
|
217
217
|
_FAILED_OVER_MESSAGE,
|
|
218
218
|
)
|
|
219
219
|
|
|
220
|
-
|
|
220
|
+
MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING: dict[
|
|
221
|
+
str, tuple[type[MaintenanceNotification], Callable]
|
|
222
|
+
] = {
|
|
221
223
|
_MIGRATING_MESSAGE: (
|
|
222
|
-
|
|
224
|
+
NodeMigratingNotification,
|
|
223
225
|
MaintenanceNotificationsParser.parse_maintenance_start_msg,
|
|
224
226
|
),
|
|
225
227
|
_MIGRATED_MESSAGE: (
|
|
226
|
-
|
|
228
|
+
NodeMigratedNotification,
|
|
227
229
|
MaintenanceNotificationsParser.parse_maintenance_completed_msg,
|
|
228
230
|
),
|
|
229
231
|
_FAILING_OVER_MESSAGE: (
|
|
230
|
-
|
|
232
|
+
NodeFailingOverNotification,
|
|
231
233
|
MaintenanceNotificationsParser.parse_maintenance_start_msg,
|
|
232
234
|
),
|
|
233
235
|
_FAILED_OVER_MESSAGE: (
|
|
234
|
-
|
|
236
|
+
NodeFailedOverNotification,
|
|
235
237
|
MaintenanceNotificationsParser.parse_maintenance_completed_msg,
|
|
236
238
|
),
|
|
237
239
|
_MOVING_MESSAGE: (
|
|
238
|
-
|
|
240
|
+
NodeMovingNotification,
|
|
239
241
|
MaintenanceNotificationsParser.parse_moving_msg,
|
|
240
242
|
),
|
|
241
243
|
}
|
|
@@ -273,14 +275,20 @@ class PushNotificationsParser(Protocol):
|
|
|
273
275
|
return self.invalidation_push_handler_func(response)
|
|
274
276
|
|
|
275
277
|
if msg_type == _MOVING_MESSAGE and self.node_moving_push_handler_func:
|
|
276
|
-
parser_function =
|
|
278
|
+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
|
|
279
|
+
msg_type
|
|
280
|
+
][1]
|
|
277
281
|
|
|
278
282
|
notification = parser_function(response)
|
|
279
283
|
return self.node_moving_push_handler_func(notification)
|
|
280
284
|
|
|
281
285
|
if msg_type in _MAINTENANCE_MESSAGES and self.maintenance_push_handler_func:
|
|
282
|
-
parser_function =
|
|
283
|
-
|
|
286
|
+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
|
|
287
|
+
msg_type
|
|
288
|
+
][1]
|
|
289
|
+
notification_type = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
|
|
290
|
+
msg_type
|
|
291
|
+
][0]
|
|
284
292
|
notification = parser_function(response, notification_type)
|
|
285
293
|
|
|
286
294
|
if notification is not None:
|
|
@@ -342,13 +350,19 @@ class AsyncPushNotificationsParser(Protocol):
|
|
|
342
350
|
msg_type = msg_type.decode()
|
|
343
351
|
|
|
344
352
|
if msg_type == _MOVING_MESSAGE and self.node_moving_push_handler_func:
|
|
345
|
-
parser_function =
|
|
353
|
+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
|
|
354
|
+
msg_type
|
|
355
|
+
][1]
|
|
346
356
|
notification = parser_function(response)
|
|
347
357
|
return await self.node_moving_push_handler_func(notification)
|
|
348
358
|
|
|
349
359
|
if msg_type in _MAINTENANCE_MESSAGES and self.maintenance_push_handler_func:
|
|
350
|
-
parser_function =
|
|
351
|
-
|
|
360
|
+
parser_function = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
|
|
361
|
+
msg_type
|
|
362
|
+
][1]
|
|
363
|
+
notification_type = MSG_TYPE_TO_MAINT_NOTIFICATION_PARSER_MAPPING[
|
|
364
|
+
msg_type
|
|
365
|
+
][0]
|
|
352
366
|
notification = parser_function(response, notification_type)
|
|
353
367
|
|
|
354
368
|
if notification is not None:
|
|
@@ -81,10 +81,11 @@ from redis.utils import (
|
|
|
81
81
|
)
|
|
82
82
|
|
|
83
83
|
if TYPE_CHECKING and SSL_AVAILABLE:
|
|
84
|
-
from ssl import TLSVersion, VerifyMode
|
|
84
|
+
from ssl import TLSVersion, VerifyFlags, VerifyMode
|
|
85
85
|
else:
|
|
86
86
|
TLSVersion = None
|
|
87
87
|
VerifyMode = None
|
|
88
|
+
VerifyFlags = None
|
|
88
89
|
|
|
89
90
|
PubSubHandler = Callable[[Dict[str, str]], Awaitable[None]]
|
|
90
91
|
_KeyT = TypeVar("_KeyT", bound=KeyT)
|
|
@@ -238,6 +239,8 @@ class Redis(
|
|
|
238
239
|
ssl_keyfile: Optional[str] = None,
|
|
239
240
|
ssl_certfile: Optional[str] = None,
|
|
240
241
|
ssl_cert_reqs: Union[str, VerifyMode] = "required",
|
|
242
|
+
ssl_include_verify_flags: Optional[List[VerifyFlags]] = None,
|
|
243
|
+
ssl_exclude_verify_flags: Optional[List[VerifyFlags]] = None,
|
|
241
244
|
ssl_ca_certs: Optional[str] = None,
|
|
242
245
|
ssl_ca_data: Optional[str] = None,
|
|
243
246
|
ssl_check_hostname: bool = True,
|
|
@@ -347,6 +350,8 @@ class Redis(
|
|
|
347
350
|
"ssl_keyfile": ssl_keyfile,
|
|
348
351
|
"ssl_certfile": ssl_certfile,
|
|
349
352
|
"ssl_cert_reqs": ssl_cert_reqs,
|
|
353
|
+
"ssl_include_verify_flags": ssl_include_verify_flags,
|
|
354
|
+
"ssl_exclude_verify_flags": ssl_exclude_verify_flags,
|
|
350
355
|
"ssl_ca_certs": ssl_ca_certs,
|
|
351
356
|
"ssl_ca_data": ssl_ca_data,
|
|
352
357
|
"ssl_check_hostname": ssl_check_hostname,
|
|
@@ -1156,9 +1161,12 @@ class PubSub:
|
|
|
1156
1161
|
return await self.handle_message(response, ignore_subscribe_messages)
|
|
1157
1162
|
return None
|
|
1158
1163
|
|
|
1159
|
-
def ping(self, message=None) -> Awaitable:
|
|
1164
|
+
def ping(self, message=None) -> Awaitable[bool]:
|
|
1160
1165
|
"""
|
|
1161
|
-
Ping the Redis server
|
|
1166
|
+
Ping the Redis server to test connectivity.
|
|
1167
|
+
|
|
1168
|
+
Sends a PING command to the Redis server and returns True if the server
|
|
1169
|
+
responds with "PONG".
|
|
1162
1170
|
"""
|
|
1163
1171
|
args = ["PING", message] if message is not None else ["PING"]
|
|
1164
1172
|
return self.execute_command(*args)
|
|
@@ -1234,6 +1242,7 @@ class PubSub:
|
|
|
1234
1242
|
*,
|
|
1235
1243
|
exception_handler: Optional["PSWorkerThreadExcHandlerT"] = None,
|
|
1236
1244
|
poll_timeout: float = 1.0,
|
|
1245
|
+
pubsub=None,
|
|
1237
1246
|
) -> None:
|
|
1238
1247
|
"""Process pub/sub messages using registered callbacks.
|
|
1239
1248
|
|
|
@@ -1258,9 +1267,14 @@ class PubSub:
|
|
|
1258
1267
|
await self.connect()
|
|
1259
1268
|
while True:
|
|
1260
1269
|
try:
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1270
|
+
if pubsub is None:
|
|
1271
|
+
await self.get_message(
|
|
1272
|
+
ignore_subscribe_messages=True, timeout=poll_timeout
|
|
1273
|
+
)
|
|
1274
|
+
else:
|
|
1275
|
+
await pubsub.get_message(
|
|
1276
|
+
ignore_subscribe_messages=True, timeout=poll_timeout
|
|
1277
|
+
)
|
|
1264
1278
|
except asyncio.CancelledError:
|
|
1265
1279
|
raise
|
|
1266
1280
|
except BaseException as e:
|
|
@@ -86,10 +86,11 @@ from redis.utils import (
|
|
|
86
86
|
)
|
|
87
87
|
|
|
88
88
|
if SSL_AVAILABLE:
|
|
89
|
-
from ssl import TLSVersion, VerifyMode
|
|
89
|
+
from ssl import TLSVersion, VerifyFlags, VerifyMode
|
|
90
90
|
else:
|
|
91
91
|
TLSVersion = None
|
|
92
92
|
VerifyMode = None
|
|
93
|
+
VerifyFlags = None
|
|
93
94
|
|
|
94
95
|
TargetNodesT = TypeVar(
|
|
95
96
|
"TargetNodesT", str, "ClusterNode", List["ClusterNode"], Dict[Any, "ClusterNode"]
|
|
@@ -299,6 +300,8 @@ class RedisCluster(AbstractRedis, AbstractRedisCluster, AsyncRedisClusterCommand
|
|
|
299
300
|
ssl_ca_certs: Optional[str] = None,
|
|
300
301
|
ssl_ca_data: Optional[str] = None,
|
|
301
302
|
ssl_cert_reqs: Union[str, VerifyMode] = "required",
|
|
303
|
+
ssl_include_verify_flags: Optional[List[VerifyFlags]] = None,
|
|
304
|
+
ssl_exclude_verify_flags: Optional[List[VerifyFlags]] = None,
|
|
302
305
|
ssl_certfile: Optional[str] = None,
|
|
303
306
|
ssl_check_hostname: bool = True,
|
|
304
307
|
ssl_keyfile: Optional[str] = None,
|
|
@@ -358,6 +361,8 @@ class RedisCluster(AbstractRedis, AbstractRedisCluster, AsyncRedisClusterCommand
|
|
|
358
361
|
"ssl_ca_certs": ssl_ca_certs,
|
|
359
362
|
"ssl_ca_data": ssl_ca_data,
|
|
360
363
|
"ssl_cert_reqs": ssl_cert_reqs,
|
|
364
|
+
"ssl_include_verify_flags": ssl_include_verify_flags,
|
|
365
|
+
"ssl_exclude_verify_flags": ssl_exclude_verify_flags,
|
|
361
366
|
"ssl_certfile": ssl_certfile,
|
|
362
367
|
"ssl_check_hostname": ssl_check_hostname,
|
|
363
368
|
"ssl_keyfile": ssl_keyfile,
|
|
@@ -404,6 +409,7 @@ class RedisCluster(AbstractRedis, AbstractRedisCluster, AsyncRedisClusterCommand
|
|
|
404
409
|
else:
|
|
405
410
|
self._event_dispatcher = event_dispatcher
|
|
406
411
|
|
|
412
|
+
self.startup_nodes = startup_nodes
|
|
407
413
|
self.nodes_manager = NodesManager(
|
|
408
414
|
startup_nodes,
|
|
409
415
|
require_full_coverage,
|
|
@@ -2248,7 +2254,10 @@ class TransactionStrategy(AbstractStrategy):
|
|
|
2248
2254
|
await self._pipe.cluster_client.nodes_manager.initialize()
|
|
2249
2255
|
self.reinitialize_counter = 0
|
|
2250
2256
|
else:
|
|
2251
|
-
|
|
2257
|
+
if isinstance(error, AskError):
|
|
2258
|
+
self._pipe.cluster_client.nodes_manager.update_moved_exception(
|
|
2259
|
+
error
|
|
2260
|
+
)
|
|
2252
2261
|
|
|
2253
2262
|
self._executing = False
|
|
2254
2263
|
|
|
@@ -30,11 +30,12 @@ from ..utils import SSL_AVAILABLE
|
|
|
30
30
|
|
|
31
31
|
if SSL_AVAILABLE:
|
|
32
32
|
import ssl
|
|
33
|
-
from ssl import SSLContext, TLSVersion
|
|
33
|
+
from ssl import SSLContext, TLSVersion, VerifyFlags
|
|
34
34
|
else:
|
|
35
35
|
ssl = None
|
|
36
36
|
TLSVersion = None
|
|
37
37
|
SSLContext = None
|
|
38
|
+
VerifyFlags = None
|
|
38
39
|
|
|
39
40
|
from ..auth.token import TokenInterface
|
|
40
41
|
from ..event import AsyncAfterConnectionReleasedEvent, EventDispatcher
|
|
@@ -212,6 +213,7 @@ class AbstractConnection:
|
|
|
212
213
|
self._connect_callbacks: List[weakref.WeakMethod[ConnectCallbackT]] = []
|
|
213
214
|
self._buffer_cutoff = 6000
|
|
214
215
|
self._re_auth_token: Optional[TokenInterface] = None
|
|
216
|
+
self._should_reconnect = False
|
|
215
217
|
|
|
216
218
|
try:
|
|
217
219
|
p = int(protocol)
|
|
@@ -342,6 +344,12 @@ class AbstractConnection:
|
|
|
342
344
|
if task and inspect.isawaitable(task):
|
|
343
345
|
await task
|
|
344
346
|
|
|
347
|
+
def mark_for_reconnect(self):
|
|
348
|
+
self._should_reconnect = True
|
|
349
|
+
|
|
350
|
+
def should_reconnect(self):
|
|
351
|
+
return self._should_reconnect
|
|
352
|
+
|
|
345
353
|
@abstractmethod
|
|
346
354
|
async def _connect(self):
|
|
347
355
|
pass
|
|
@@ -793,6 +801,8 @@ class SSLConnection(Connection):
|
|
|
793
801
|
ssl_keyfile: Optional[str] = None,
|
|
794
802
|
ssl_certfile: Optional[str] = None,
|
|
795
803
|
ssl_cert_reqs: Union[str, ssl.VerifyMode] = "required",
|
|
804
|
+
ssl_include_verify_flags: Optional[List["ssl.VerifyFlags"]] = None,
|
|
805
|
+
ssl_exclude_verify_flags: Optional[List["ssl.VerifyFlags"]] = None,
|
|
796
806
|
ssl_ca_certs: Optional[str] = None,
|
|
797
807
|
ssl_ca_data: Optional[str] = None,
|
|
798
808
|
ssl_check_hostname: bool = True,
|
|
@@ -807,6 +817,8 @@ class SSLConnection(Connection):
|
|
|
807
817
|
keyfile=ssl_keyfile,
|
|
808
818
|
certfile=ssl_certfile,
|
|
809
819
|
cert_reqs=ssl_cert_reqs,
|
|
820
|
+
include_verify_flags=ssl_include_verify_flags,
|
|
821
|
+
exclude_verify_flags=ssl_exclude_verify_flags,
|
|
810
822
|
ca_certs=ssl_ca_certs,
|
|
811
823
|
ca_data=ssl_ca_data,
|
|
812
824
|
check_hostname=ssl_check_hostname,
|
|
@@ -832,6 +844,14 @@ class SSLConnection(Connection):
|
|
|
832
844
|
def cert_reqs(self):
|
|
833
845
|
return self.ssl_context.cert_reqs
|
|
834
846
|
|
|
847
|
+
@property
|
|
848
|
+
def include_verify_flags(self):
|
|
849
|
+
return self.ssl_context.include_verify_flags
|
|
850
|
+
|
|
851
|
+
@property
|
|
852
|
+
def exclude_verify_flags(self):
|
|
853
|
+
return self.ssl_context.exclude_verify_flags
|
|
854
|
+
|
|
835
855
|
@property
|
|
836
856
|
def ca_certs(self):
|
|
837
857
|
return self.ssl_context.ca_certs
|
|
@@ -854,6 +874,8 @@ class RedisSSLContext:
|
|
|
854
874
|
"keyfile",
|
|
855
875
|
"certfile",
|
|
856
876
|
"cert_reqs",
|
|
877
|
+
"include_verify_flags",
|
|
878
|
+
"exclude_verify_flags",
|
|
857
879
|
"ca_certs",
|
|
858
880
|
"ca_data",
|
|
859
881
|
"context",
|
|
@@ -867,6 +889,8 @@ class RedisSSLContext:
|
|
|
867
889
|
keyfile: Optional[str] = None,
|
|
868
890
|
certfile: Optional[str] = None,
|
|
869
891
|
cert_reqs: Optional[Union[str, ssl.VerifyMode]] = None,
|
|
892
|
+
include_verify_flags: Optional[List["ssl.VerifyFlags"]] = None,
|
|
893
|
+
exclude_verify_flags: Optional[List["ssl.VerifyFlags"]] = None,
|
|
870
894
|
ca_certs: Optional[str] = None,
|
|
871
895
|
ca_data: Optional[str] = None,
|
|
872
896
|
check_hostname: bool = False,
|
|
@@ -892,6 +916,8 @@ class RedisSSLContext:
|
|
|
892
916
|
)
|
|
893
917
|
cert_reqs = CERT_REQS[cert_reqs]
|
|
894
918
|
self.cert_reqs = cert_reqs
|
|
919
|
+
self.include_verify_flags = include_verify_flags
|
|
920
|
+
self.exclude_verify_flags = exclude_verify_flags
|
|
895
921
|
self.ca_certs = ca_certs
|
|
896
922
|
self.ca_data = ca_data
|
|
897
923
|
self.check_hostname = (
|
|
@@ -906,6 +932,12 @@ class RedisSSLContext:
|
|
|
906
932
|
context = ssl.create_default_context()
|
|
907
933
|
context.check_hostname = self.check_hostname
|
|
908
934
|
context.verify_mode = self.cert_reqs
|
|
935
|
+
if self.include_verify_flags:
|
|
936
|
+
for flag in self.include_verify_flags:
|
|
937
|
+
context.verify_flags |= flag
|
|
938
|
+
if self.exclude_verify_flags:
|
|
939
|
+
for flag in self.exclude_verify_flags:
|
|
940
|
+
context.verify_flags &= ~flag
|
|
909
941
|
if self.certfile and self.keyfile:
|
|
910
942
|
context.load_cert_chain(certfile=self.certfile, keyfile=self.keyfile)
|
|
911
943
|
if self.ca_certs or self.ca_data:
|
|
@@ -953,6 +985,20 @@ def to_bool(value) -> Optional[bool]:
|
|
|
953
985
|
return bool(value)
|
|
954
986
|
|
|
955
987
|
|
|
988
|
+
def parse_ssl_verify_flags(value):
|
|
989
|
+
# flags are passed in as a string representation of a list,
|
|
990
|
+
# e.g. VERIFY_X509_STRICT, VERIFY_X509_PARTIAL_CHAIN
|
|
991
|
+
verify_flags_str = value.replace("[", "").replace("]", "")
|
|
992
|
+
|
|
993
|
+
verify_flags = []
|
|
994
|
+
for flag in verify_flags_str.split(","):
|
|
995
|
+
flag = flag.strip()
|
|
996
|
+
if not hasattr(VerifyFlags, flag):
|
|
997
|
+
raise ValueError(f"Invalid ssl verify flag: {flag}")
|
|
998
|
+
verify_flags.append(getattr(VerifyFlags, flag))
|
|
999
|
+
return verify_flags
|
|
1000
|
+
|
|
1001
|
+
|
|
956
1002
|
URL_QUERY_ARGUMENT_PARSERS: Mapping[str, Callable[..., object]] = MappingProxyType(
|
|
957
1003
|
{
|
|
958
1004
|
"db": int,
|
|
@@ -963,6 +1009,8 @@ URL_QUERY_ARGUMENT_PARSERS: Mapping[str, Callable[..., object]] = MappingProxyTy
|
|
|
963
1009
|
"max_connections": int,
|
|
964
1010
|
"health_check_interval": int,
|
|
965
1011
|
"ssl_check_hostname": to_bool,
|
|
1012
|
+
"ssl_include_verify_flags": parse_ssl_verify_flags,
|
|
1013
|
+
"ssl_exclude_verify_flags": parse_ssl_verify_flags,
|
|
966
1014
|
"timeout": float,
|
|
967
1015
|
}
|
|
968
1016
|
)
|
|
@@ -1021,6 +1069,7 @@ def parse_url(url: str) -> ConnectKwargs:
|
|
|
1021
1069
|
|
|
1022
1070
|
if parsed.scheme == "rediss":
|
|
1023
1071
|
kwargs["connection_class"] = SSLConnection
|
|
1072
|
+
|
|
1024
1073
|
else:
|
|
1025
1074
|
valid_schemes = "redis://, rediss://, unix://"
|
|
1026
1075
|
raise ValueError(
|
|
@@ -1198,6 +1247,9 @@ class ConnectionPool:
|
|
|
1198
1247
|
# Connections should always be returned to the correct pool,
|
|
1199
1248
|
# not doing so is an error that will cause an exception here.
|
|
1200
1249
|
self._in_use_connections.remove(connection)
|
|
1250
|
+
if connection.should_reconnect():
|
|
1251
|
+
await connection.disconnect()
|
|
1252
|
+
|
|
1201
1253
|
self._available_connections.append(connection)
|
|
1202
1254
|
await self._event_dispatcher.dispatch_async(
|
|
1203
1255
|
AsyncAfterConnectionReleasedEvent(connection)
|
|
@@ -1225,6 +1277,14 @@ class ConnectionPool:
|
|
|
1225
1277
|
if exc:
|
|
1226
1278
|
raise exc
|
|
1227
1279
|
|
|
1280
|
+
async def update_active_connections_for_reconnect(self):
|
|
1281
|
+
"""
|
|
1282
|
+
Mark all active connections for reconnect.
|
|
1283
|
+
"""
|
|
1284
|
+
async with self._lock:
|
|
1285
|
+
for conn in self._in_use_connections:
|
|
1286
|
+
conn.mark_for_reconnect()
|
|
1287
|
+
|
|
1228
1288
|
async def aclose(self) -> None:
|
|
1229
1289
|
"""Close the pool, disconnecting all connections"""
|
|
1230
1290
|
await self.disconnect()
|