redis 7.0.0b1__py3-none-any.whl → 7.0.0b2__py3-none-any.whl
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/__init__.py +1 -1
- redis/_parsers/base.py +36 -22
- redis/asyncio/client.py +6 -1
- redis/asyncio/cluster.py +6 -1
- redis/asyncio/connection.py +43 -1
- redis/client.py +19 -15
- redis/cluster.py +2 -0
- redis/connection.py +206 -151
- redis/{maintenance_events.py → maint_notifications.py} +154 -140
- {redis-7.0.0b1.dist-info → redis-7.0.0b2.dist-info}/METADATA +1 -1
- {redis-7.0.0b1.dist-info → redis-7.0.0b2.dist-info}/RECORD +13 -13
- {redis-7.0.0b1.dist-info → redis-7.0.0b2.dist-info}/WHEEL +0 -0
- {redis-7.0.0b1.dist-info → redis-7.0.0b2.dist-info}/licenses/LICENSE +0 -0
redis/connection.py
CHANGED
|
@@ -47,11 +47,11 @@ from .exceptions import (
|
|
|
47
47
|
ResponseError,
|
|
48
48
|
TimeoutError,
|
|
49
49
|
)
|
|
50
|
-
from .
|
|
51
|
-
MaintenanceEventConnectionHandler,
|
|
52
|
-
MaintenanceEventPoolHandler,
|
|
53
|
-
MaintenanceEventsConfig,
|
|
50
|
+
from .maint_notifications import (
|
|
54
51
|
MaintenanceState,
|
|
52
|
+
MaintNotificationsConfig,
|
|
53
|
+
MaintNotificationsConnectionHandler,
|
|
54
|
+
MaintNotificationsPoolHandler,
|
|
55
55
|
)
|
|
56
56
|
from .retry import Retry
|
|
57
57
|
from .utils import (
|
|
@@ -68,8 +68,10 @@ from .utils import (
|
|
|
68
68
|
|
|
69
69
|
if SSL_AVAILABLE:
|
|
70
70
|
import ssl
|
|
71
|
+
from ssl import VerifyFlags
|
|
71
72
|
else:
|
|
72
73
|
ssl = None
|
|
74
|
+
VerifyFlags = None
|
|
73
75
|
|
|
74
76
|
if HIREDIS_AVAILABLE:
|
|
75
77
|
import hiredis
|
|
@@ -177,7 +179,7 @@ class ConnectionInterface:
|
|
|
177
179
|
pass
|
|
178
180
|
|
|
179
181
|
@abstractmethod
|
|
180
|
-
def
|
|
182
|
+
def set_maint_notifications_pool_handler(self, maint_notifications_pool_handler):
|
|
181
183
|
pass
|
|
182
184
|
|
|
183
185
|
@abstractmethod
|
|
@@ -289,7 +291,7 @@ class ConnectionInterface:
|
|
|
289
291
|
pass
|
|
290
292
|
|
|
291
293
|
@abstractmethod
|
|
292
|
-
def update_current_socket_timeout(self,
|
|
294
|
+
def update_current_socket_timeout(self, relaxed_timeout: Optional[float] = None):
|
|
293
295
|
"""
|
|
294
296
|
Update the timeout for the current socket.
|
|
295
297
|
"""
|
|
@@ -299,7 +301,7 @@ class ConnectionInterface:
|
|
|
299
301
|
def set_tmp_settings(
|
|
300
302
|
self,
|
|
301
303
|
tmp_host_address: Optional[str] = None,
|
|
302
|
-
|
|
304
|
+
tmp_relaxed_timeout: Optional[float] = None,
|
|
303
305
|
):
|
|
304
306
|
"""
|
|
305
307
|
Updates temporary host address and timeout settings for the connection.
|
|
@@ -310,7 +312,7 @@ class ConnectionInterface:
|
|
|
310
312
|
def reset_tmp_settings(
|
|
311
313
|
self,
|
|
312
314
|
reset_host_address: bool = False,
|
|
313
|
-
|
|
315
|
+
reset_relaxed_timeout: bool = False,
|
|
314
316
|
):
|
|
315
317
|
"""
|
|
316
318
|
Resets temporary host address and timeout settings for the connection.
|
|
@@ -345,10 +347,12 @@ class AbstractConnection(ConnectionInterface):
|
|
|
345
347
|
protocol: Optional[int] = 2,
|
|
346
348
|
command_packer: Optional[Callable[[], None]] = None,
|
|
347
349
|
event_dispatcher: Optional[EventDispatcher] = None,
|
|
348
|
-
|
|
349
|
-
|
|
350
|
+
maint_notifications_pool_handler: Optional[
|
|
351
|
+
MaintNotificationsPoolHandler
|
|
352
|
+
] = None,
|
|
353
|
+
maint_notifications_config: Optional[MaintNotificationsConfig] = None,
|
|
350
354
|
maintenance_state: "MaintenanceState" = MaintenanceState.NONE,
|
|
351
|
-
|
|
355
|
+
maintenance_notification_hash: Optional[int] = None,
|
|
352
356
|
orig_host_address: Optional[str] = None,
|
|
353
357
|
orig_socket_timeout: Optional[float] = None,
|
|
354
358
|
orig_socket_connect_timeout: Optional[float] = None,
|
|
@@ -428,11 +432,11 @@ class AbstractConnection(ConnectionInterface):
|
|
|
428
432
|
parser_class = _RESP3Parser
|
|
429
433
|
self.set_parser(parser_class)
|
|
430
434
|
|
|
431
|
-
self.
|
|
435
|
+
self.maint_notifications_config = maint_notifications_config
|
|
432
436
|
|
|
433
|
-
# Set up maintenance
|
|
434
|
-
self.
|
|
435
|
-
|
|
437
|
+
# Set up maintenance notifications if enabled
|
|
438
|
+
self._configure_maintenance_notifications(
|
|
439
|
+
maint_notifications_pool_handler,
|
|
436
440
|
orig_host_address,
|
|
437
441
|
orig_socket_timeout,
|
|
438
442
|
orig_socket_connect_timeout,
|
|
@@ -440,7 +444,7 @@ class AbstractConnection(ConnectionInterface):
|
|
|
440
444
|
|
|
441
445
|
self._should_reconnect = False
|
|
442
446
|
self.maintenance_state = maintenance_state
|
|
443
|
-
self.
|
|
447
|
+
self.maintenance_notification_hash = maintenance_notification_hash
|
|
444
448
|
|
|
445
449
|
self._command_packer = self._construct_command_packer(command_packer)
|
|
446
450
|
|
|
@@ -497,33 +501,33 @@ class AbstractConnection(ConnectionInterface):
|
|
|
497
501
|
"""
|
|
498
502
|
self._parser = parser_class(socket_read_size=self._socket_read_size)
|
|
499
503
|
|
|
500
|
-
def
|
|
504
|
+
def _configure_maintenance_notifications(
|
|
501
505
|
self,
|
|
502
|
-
|
|
506
|
+
maint_notifications_pool_handler=None,
|
|
503
507
|
orig_host_address=None,
|
|
504
508
|
orig_socket_timeout=None,
|
|
505
509
|
orig_socket_connect_timeout=None,
|
|
506
510
|
):
|
|
507
|
-
"""Enable maintenance
|
|
511
|
+
"""Enable maintenance notifications by setting up handlers and storing original connection parameters."""
|
|
508
512
|
if (
|
|
509
|
-
not self.
|
|
510
|
-
or not self.
|
|
513
|
+
not self.maint_notifications_config
|
|
514
|
+
or not self.maint_notifications_config.enabled
|
|
511
515
|
):
|
|
512
|
-
self.
|
|
516
|
+
self._maint_notifications_connection_handler = None
|
|
513
517
|
return
|
|
514
518
|
|
|
515
519
|
# Set up pool handler if available
|
|
516
|
-
if
|
|
520
|
+
if maint_notifications_pool_handler:
|
|
517
521
|
self._parser.set_node_moving_push_handler(
|
|
518
|
-
|
|
522
|
+
maint_notifications_pool_handler.handle_notification
|
|
519
523
|
)
|
|
520
524
|
|
|
521
525
|
# Set up connection handler
|
|
522
|
-
self.
|
|
523
|
-
self, self.
|
|
526
|
+
self._maint_notifications_connection_handler = (
|
|
527
|
+
MaintNotificationsConnectionHandler(self, self.maint_notifications_config)
|
|
524
528
|
)
|
|
525
529
|
self._parser.set_maintenance_push_handler(
|
|
526
|
-
self.
|
|
530
|
+
self._maint_notifications_connection_handler.handle_notification
|
|
527
531
|
)
|
|
528
532
|
|
|
529
533
|
# Store original connection parameters
|
|
@@ -537,27 +541,27 @@ class AbstractConnection(ConnectionInterface):
|
|
|
537
541
|
else self.socket_connect_timeout
|
|
538
542
|
)
|
|
539
543
|
|
|
540
|
-
def
|
|
541
|
-
self,
|
|
544
|
+
def set_maint_notifications_pool_handler(
|
|
545
|
+
self, maint_notifications_pool_handler: MaintNotificationsPoolHandler
|
|
542
546
|
):
|
|
543
|
-
|
|
547
|
+
maint_notifications_pool_handler.set_connection(self)
|
|
544
548
|
self._parser.set_node_moving_push_handler(
|
|
545
|
-
|
|
549
|
+
maint_notifications_pool_handler.handle_notification
|
|
546
550
|
)
|
|
547
551
|
|
|
548
|
-
# Update maintenance
|
|
549
|
-
if not self.
|
|
550
|
-
self.
|
|
551
|
-
|
|
552
|
-
self,
|
|
552
|
+
# Update maintenance notification connection handler if it doesn't exist
|
|
553
|
+
if not self._maint_notifications_connection_handler:
|
|
554
|
+
self._maint_notifications_connection_handler = (
|
|
555
|
+
MaintNotificationsConnectionHandler(
|
|
556
|
+
self, maint_notifications_pool_handler.config
|
|
553
557
|
)
|
|
554
558
|
)
|
|
555
559
|
self._parser.set_maintenance_push_handler(
|
|
556
|
-
self.
|
|
560
|
+
self._maint_notifications_connection_handler.handle_notification
|
|
557
561
|
)
|
|
558
562
|
else:
|
|
559
|
-
self.
|
|
560
|
-
|
|
563
|
+
self._maint_notifications_connection_handler.config = (
|
|
564
|
+
maint_notifications_pool_handler.config
|
|
561
565
|
)
|
|
562
566
|
|
|
563
567
|
def connect(self):
|
|
@@ -684,17 +688,21 @@ class AbstractConnection(ConnectionInterface):
|
|
|
684
688
|
):
|
|
685
689
|
raise ConnectionError("Invalid RESP version")
|
|
686
690
|
|
|
687
|
-
# Send maintenance notifications handshake if RESP3 is active
|
|
691
|
+
# Send maintenance notifications handshake if RESP3 is active
|
|
692
|
+
# and maintenance notifications are enabled
|
|
688
693
|
# and we have a host to determine the endpoint type from
|
|
694
|
+
# When the maint_notifications_config enabled mode is "auto",
|
|
695
|
+
# we just log a warning if the handshake fails
|
|
696
|
+
# When the mode is enabled=True, we raise an exception in case of failure
|
|
689
697
|
if (
|
|
690
698
|
self.protocol not in [2, "2"]
|
|
691
|
-
and self.
|
|
692
|
-
and self.
|
|
693
|
-
and self.
|
|
699
|
+
and self.maint_notifications_config
|
|
700
|
+
and self.maint_notifications_config.enabled
|
|
701
|
+
and self._maint_notifications_connection_handler
|
|
694
702
|
and hasattr(self, "host")
|
|
695
703
|
):
|
|
696
704
|
try:
|
|
697
|
-
endpoint_type = self.
|
|
705
|
+
endpoint_type = self.maint_notifications_config.get_endpoint_type(
|
|
698
706
|
self.host, self
|
|
699
707
|
)
|
|
700
708
|
self.send_command(
|
|
@@ -707,15 +715,21 @@ class AbstractConnection(ConnectionInterface):
|
|
|
707
715
|
)
|
|
708
716
|
response = self.read_response()
|
|
709
717
|
if str_if_bytes(response) != "OK":
|
|
710
|
-
raise
|
|
718
|
+
raise ResponseError(
|
|
711
719
|
"The server doesn't support maintenance notifications"
|
|
712
720
|
)
|
|
713
721
|
except Exception as e:
|
|
714
|
-
|
|
715
|
-
|
|
722
|
+
if (
|
|
723
|
+
isinstance(e, ResponseError)
|
|
724
|
+
and self.maint_notifications_config.enabled == "auto"
|
|
725
|
+
):
|
|
726
|
+
# Log warning but don't fail the connection
|
|
727
|
+
import logging
|
|
716
728
|
|
|
717
|
-
|
|
718
|
-
|
|
729
|
+
logger = logging.getLogger(__name__)
|
|
730
|
+
logger.warning(f"Failed to enable maintenance notifications: {e}")
|
|
731
|
+
else:
|
|
732
|
+
raise
|
|
719
733
|
|
|
720
734
|
# if a client_name is given, set it
|
|
721
735
|
if self.client_name:
|
|
@@ -1022,9 +1036,9 @@ class AbstractConnection(ConnectionInterface):
|
|
|
1022
1036
|
def should_reconnect(self):
|
|
1023
1037
|
return self._should_reconnect
|
|
1024
1038
|
|
|
1025
|
-
def update_current_socket_timeout(self,
|
|
1039
|
+
def update_current_socket_timeout(self, relaxed_timeout: Optional[float] = None):
|
|
1026
1040
|
if self._sock:
|
|
1027
|
-
timeout =
|
|
1041
|
+
timeout = relaxed_timeout if relaxed_timeout != -1 else self.socket_timeout
|
|
1028
1042
|
self._sock.settimeout(timeout)
|
|
1029
1043
|
self.update_parser_buffer_timeout(timeout)
|
|
1030
1044
|
|
|
@@ -1035,25 +1049,25 @@ class AbstractConnection(ConnectionInterface):
|
|
|
1035
1049
|
def set_tmp_settings(
|
|
1036
1050
|
self,
|
|
1037
1051
|
tmp_host_address: Optional[Union[str, object]] = SENTINEL,
|
|
1038
|
-
|
|
1052
|
+
tmp_relaxed_timeout: Optional[float] = None,
|
|
1039
1053
|
):
|
|
1040
1054
|
"""
|
|
1041
1055
|
The value of SENTINEL is used to indicate that the property should not be updated.
|
|
1042
1056
|
"""
|
|
1043
1057
|
if tmp_host_address is not SENTINEL:
|
|
1044
1058
|
self.host = tmp_host_address
|
|
1045
|
-
if
|
|
1046
|
-
self.socket_timeout =
|
|
1047
|
-
self.socket_connect_timeout =
|
|
1059
|
+
if tmp_relaxed_timeout != -1:
|
|
1060
|
+
self.socket_timeout = tmp_relaxed_timeout
|
|
1061
|
+
self.socket_connect_timeout = tmp_relaxed_timeout
|
|
1048
1062
|
|
|
1049
1063
|
def reset_tmp_settings(
|
|
1050
1064
|
self,
|
|
1051
1065
|
reset_host_address: bool = False,
|
|
1052
|
-
|
|
1066
|
+
reset_relaxed_timeout: bool = False,
|
|
1053
1067
|
):
|
|
1054
1068
|
if reset_host_address:
|
|
1055
1069
|
self.host = self.orig_host_address
|
|
1056
|
-
if
|
|
1070
|
+
if reset_relaxed_timeout:
|
|
1057
1071
|
self.socket_timeout = self.orig_socket_timeout
|
|
1058
1072
|
self.socket_connect_timeout = self.orig_socket_connect_timeout
|
|
1059
1073
|
|
|
@@ -1358,6 +1372,8 @@ class SSLConnection(Connection):
|
|
|
1358
1372
|
ssl_keyfile=None,
|
|
1359
1373
|
ssl_certfile=None,
|
|
1360
1374
|
ssl_cert_reqs="required",
|
|
1375
|
+
ssl_include_verify_flags: Optional[List["VerifyFlags"]] = None,
|
|
1376
|
+
ssl_exclude_verify_flags: Optional[List["VerifyFlags"]] = None,
|
|
1361
1377
|
ssl_ca_certs=None,
|
|
1362
1378
|
ssl_ca_data=None,
|
|
1363
1379
|
ssl_check_hostname=True,
|
|
@@ -1376,7 +1392,10 @@ class SSLConnection(Connection):
|
|
|
1376
1392
|
Args:
|
|
1377
1393
|
ssl_keyfile: Path to an ssl private key. Defaults to None.
|
|
1378
1394
|
ssl_certfile: Path to an ssl certificate. Defaults to None.
|
|
1379
|
-
ssl_cert_reqs: The string value for the SSLContext.verify_mode (none, optional, required),
|
|
1395
|
+
ssl_cert_reqs: The string value for the SSLContext.verify_mode (none, optional, required),
|
|
1396
|
+
or an ssl.VerifyMode. Defaults to "required".
|
|
1397
|
+
ssl_include_verify_flags: A list of flags to be included in the SSLContext.verify_flags. Defaults to None.
|
|
1398
|
+
ssl_exclude_verify_flags: A list of flags to be excluded from the SSLContext.verify_flags. Defaults to None.
|
|
1380
1399
|
ssl_ca_certs: The path to a file of concatenated CA certificates in PEM format. Defaults to None.
|
|
1381
1400
|
ssl_ca_data: Either an ASCII string of one or more PEM-encoded certificates or a bytes-like object of DER-encoded certificates.
|
|
1382
1401
|
ssl_check_hostname: If set, match the hostname during the SSL handshake. Defaults to True.
|
|
@@ -1412,6 +1431,8 @@ class SSLConnection(Connection):
|
|
|
1412
1431
|
)
|
|
1413
1432
|
ssl_cert_reqs = CERT_REQS[ssl_cert_reqs]
|
|
1414
1433
|
self.cert_reqs = ssl_cert_reqs
|
|
1434
|
+
self.ssl_include_verify_flags = ssl_include_verify_flags
|
|
1435
|
+
self.ssl_exclude_verify_flags = ssl_exclude_verify_flags
|
|
1415
1436
|
self.ca_certs = ssl_ca_certs
|
|
1416
1437
|
self.ca_data = ssl_ca_data
|
|
1417
1438
|
self.ca_path = ssl_ca_path
|
|
@@ -1451,6 +1472,12 @@ class SSLConnection(Connection):
|
|
|
1451
1472
|
context = ssl.create_default_context()
|
|
1452
1473
|
context.check_hostname = self.check_hostname
|
|
1453
1474
|
context.verify_mode = self.cert_reqs
|
|
1475
|
+
if self.ssl_include_verify_flags:
|
|
1476
|
+
for flag in self.ssl_include_verify_flags:
|
|
1477
|
+
context.verify_flags |= flag
|
|
1478
|
+
if self.ssl_exclude_verify_flags:
|
|
1479
|
+
for flag in self.ssl_exclude_verify_flags:
|
|
1480
|
+
context.verify_flags &= ~flag
|
|
1454
1481
|
if self.certfile or self.keyfile:
|
|
1455
1482
|
context.load_cert_chain(
|
|
1456
1483
|
certfile=self.certfile,
|
|
@@ -1564,6 +1591,20 @@ def to_bool(value):
|
|
|
1564
1591
|
return bool(value)
|
|
1565
1592
|
|
|
1566
1593
|
|
|
1594
|
+
def parse_ssl_verify_flags(value):
|
|
1595
|
+
# flags are passed in as a string representation of a list,
|
|
1596
|
+
# e.g. VERIFY_X509_STRICT, VERIFY_X509_PARTIAL_CHAIN
|
|
1597
|
+
verify_flags_str = value.replace("[", "").replace("]", "")
|
|
1598
|
+
|
|
1599
|
+
verify_flags = []
|
|
1600
|
+
for flag in verify_flags_str.split(","):
|
|
1601
|
+
flag = flag.strip()
|
|
1602
|
+
if not hasattr(VerifyFlags, flag):
|
|
1603
|
+
raise ValueError(f"Invalid ssl verify flag: {flag}")
|
|
1604
|
+
verify_flags.append(getattr(VerifyFlags, flag))
|
|
1605
|
+
return verify_flags
|
|
1606
|
+
|
|
1607
|
+
|
|
1567
1608
|
URL_QUERY_ARGUMENT_PARSERS = {
|
|
1568
1609
|
"db": int,
|
|
1569
1610
|
"socket_timeout": float,
|
|
@@ -1574,6 +1615,8 @@ URL_QUERY_ARGUMENT_PARSERS = {
|
|
|
1574
1615
|
"max_connections": int,
|
|
1575
1616
|
"health_check_interval": int,
|
|
1576
1617
|
"ssl_check_hostname": to_bool,
|
|
1618
|
+
"ssl_include_verify_flags": parse_ssl_verify_flags,
|
|
1619
|
+
"ssl_exclude_verify_flags": parse_ssl_verify_flags,
|
|
1577
1620
|
"timeout": float,
|
|
1578
1621
|
}
|
|
1579
1622
|
|
|
@@ -1742,20 +1785,20 @@ class ConnectionPool:
|
|
|
1742
1785
|
connection_kwargs.pop("cache_config", None)
|
|
1743
1786
|
|
|
1744
1787
|
if self.connection_kwargs.get(
|
|
1745
|
-
"
|
|
1746
|
-
) or self.connection_kwargs.get("
|
|
1788
|
+
"maint_notifications_pool_handler"
|
|
1789
|
+
) or self.connection_kwargs.get("maint_notifications_config"):
|
|
1747
1790
|
if self.connection_kwargs.get("protocol") not in [3, "3"]:
|
|
1748
1791
|
raise RedisError(
|
|
1749
1792
|
"Push handlers on connection are only supported with RESP version 3"
|
|
1750
1793
|
)
|
|
1751
|
-
config = self.connection_kwargs.get("
|
|
1752
|
-
self.connection_kwargs.get("
|
|
1753
|
-
if self.connection_kwargs.get("
|
|
1794
|
+
config = self.connection_kwargs.get("maint_notifications_config", None) or (
|
|
1795
|
+
self.connection_kwargs.get("maint_notifications_pool_handler").config
|
|
1796
|
+
if self.connection_kwargs.get("maint_notifications_pool_handler")
|
|
1754
1797
|
else None
|
|
1755
1798
|
)
|
|
1756
1799
|
|
|
1757
1800
|
if config and config.enabled:
|
|
1758
|
-
self.
|
|
1801
|
+
self._update_connection_kwargs_for_maint_notifications()
|
|
1759
1802
|
|
|
1760
1803
|
self._event_dispatcher = self.connection_kwargs.get("event_dispatcher", None)
|
|
1761
1804
|
if self._event_dispatcher is None:
|
|
@@ -1791,46 +1834,54 @@ class ConnectionPool:
|
|
|
1791
1834
|
"""
|
|
1792
1835
|
return self.connection_kwargs.get("protocol", None)
|
|
1793
1836
|
|
|
1794
|
-
def
|
|
1837
|
+
def maint_notifications_pool_handler_enabled(self):
|
|
1795
1838
|
"""
|
|
1796
1839
|
Returns:
|
|
1797
|
-
True if the maintenance
|
|
1840
|
+
True if the maintenance notifications pool handler is enabled, False otherwise.
|
|
1798
1841
|
"""
|
|
1799
|
-
|
|
1800
|
-
"
|
|
1842
|
+
maint_notifications_config = self.connection_kwargs.get(
|
|
1843
|
+
"maint_notifications_config", None
|
|
1801
1844
|
)
|
|
1802
1845
|
|
|
1803
|
-
return
|
|
1846
|
+
return maint_notifications_config and maint_notifications_config.enabled
|
|
1804
1847
|
|
|
1805
|
-
def
|
|
1806
|
-
self,
|
|
1848
|
+
def set_maint_notifications_pool_handler(
|
|
1849
|
+
self, maint_notifications_pool_handler: MaintNotificationsPoolHandler
|
|
1807
1850
|
):
|
|
1808
1851
|
self.connection_kwargs.update(
|
|
1809
1852
|
{
|
|
1810
|
-
"
|
|
1811
|
-
"
|
|
1853
|
+
"maint_notifications_pool_handler": maint_notifications_pool_handler,
|
|
1854
|
+
"maint_notifications_config": maint_notifications_pool_handler.config,
|
|
1812
1855
|
}
|
|
1813
1856
|
)
|
|
1814
|
-
self.
|
|
1857
|
+
self._update_connection_kwargs_for_maint_notifications()
|
|
1815
1858
|
|
|
1816
|
-
self.
|
|
1817
|
-
|
|
1859
|
+
self._update_maint_notifications_configs_for_connections(
|
|
1860
|
+
maint_notifications_pool_handler
|
|
1818
1861
|
)
|
|
1819
1862
|
|
|
1820
|
-
def
|
|
1821
|
-
self,
|
|
1863
|
+
def _update_maint_notifications_configs_for_connections(
|
|
1864
|
+
self, maint_notifications_pool_handler
|
|
1822
1865
|
):
|
|
1823
|
-
"""Update the maintenance
|
|
1866
|
+
"""Update the maintenance notifications config for all connections in the pool."""
|
|
1824
1867
|
with self._lock:
|
|
1825
1868
|
for conn in self._available_connections:
|
|
1826
|
-
conn.
|
|
1827
|
-
|
|
1869
|
+
conn.set_maint_notifications_pool_handler(
|
|
1870
|
+
maint_notifications_pool_handler
|
|
1871
|
+
)
|
|
1872
|
+
conn.maint_notifications_config = (
|
|
1873
|
+
maint_notifications_pool_handler.config
|
|
1874
|
+
)
|
|
1828
1875
|
for conn in self._in_use_connections:
|
|
1829
|
-
conn.
|
|
1830
|
-
|
|
1876
|
+
conn.set_maint_notifications_pool_handler(
|
|
1877
|
+
maint_notifications_pool_handler
|
|
1878
|
+
)
|
|
1879
|
+
conn.maint_notifications_config = (
|
|
1880
|
+
maint_notifications_pool_handler.config
|
|
1881
|
+
)
|
|
1831
1882
|
|
|
1832
|
-
def
|
|
1833
|
-
"""Store original connection parameters for maintenance
|
|
1883
|
+
def _update_connection_kwargs_for_maint_notifications(self):
|
|
1884
|
+
"""Store original connection parameters for maintenance notifications."""
|
|
1834
1885
|
if self.connection_kwargs.get("orig_host_address", None) is None:
|
|
1835
1886
|
# If orig_host_address is None it means we haven't
|
|
1836
1887
|
# configured the original values yet
|
|
@@ -1936,7 +1987,7 @@ class ConnectionPool:
|
|
|
1936
1987
|
if (
|
|
1937
1988
|
connection.can_read()
|
|
1938
1989
|
and self.cache is None
|
|
1939
|
-
and not self.
|
|
1990
|
+
and not self.maint_notifications_pool_handler_enabled()
|
|
1940
1991
|
):
|
|
1941
1992
|
raise ConnectionError("Connection has data")
|
|
1942
1993
|
except (ConnectionError, TimeoutError, OSError):
|
|
@@ -2053,13 +2104,13 @@ class ConnectionPool:
|
|
|
2053
2104
|
self,
|
|
2054
2105
|
conn: "Connection",
|
|
2055
2106
|
matching_pattern: Literal[
|
|
2056
|
-
"connected_address", "configured_address", "
|
|
2107
|
+
"connected_address", "configured_address", "notification_hash"
|
|
2057
2108
|
] = "connected_address",
|
|
2058
2109
|
matching_address: Optional[str] = None,
|
|
2059
|
-
|
|
2110
|
+
matching_notification_hash: Optional[int] = None,
|
|
2060
2111
|
) -> bool:
|
|
2061
2112
|
"""
|
|
2062
|
-
Check if the connection should be updated based on the matching
|
|
2113
|
+
Check if the connection should be updated based on the matching criteria.
|
|
2063
2114
|
"""
|
|
2064
2115
|
if matching_pattern == "connected_address":
|
|
2065
2116
|
if matching_address and conn.getpeername() != matching_address:
|
|
@@ -2067,10 +2118,10 @@ class ConnectionPool:
|
|
|
2067
2118
|
elif matching_pattern == "configured_address":
|
|
2068
2119
|
if matching_address and conn.host != matching_address:
|
|
2069
2120
|
return False
|
|
2070
|
-
elif matching_pattern == "
|
|
2121
|
+
elif matching_pattern == "notification_hash":
|
|
2071
2122
|
if (
|
|
2072
|
-
|
|
2073
|
-
and conn.
|
|
2123
|
+
matching_notification_hash
|
|
2124
|
+
and conn.maintenance_notification_hash != matching_notification_hash
|
|
2074
2125
|
):
|
|
2075
2126
|
return False
|
|
2076
2127
|
return True
|
|
@@ -2079,12 +2130,12 @@ class ConnectionPool:
|
|
|
2079
2130
|
self,
|
|
2080
2131
|
conn: "Connection",
|
|
2081
2132
|
state: Optional["MaintenanceState"] = None,
|
|
2082
|
-
|
|
2133
|
+
maintenance_notification_hash: Optional[int] = None,
|
|
2083
2134
|
host_address: Optional[str] = None,
|
|
2084
|
-
|
|
2085
|
-
|
|
2135
|
+
relaxed_timeout: Optional[float] = None,
|
|
2136
|
+
update_notification_hash: bool = False,
|
|
2086
2137
|
reset_host_address: bool = False,
|
|
2087
|
-
|
|
2138
|
+
reset_relaxed_timeout: bool = False,
|
|
2088
2139
|
):
|
|
2089
2140
|
"""
|
|
2090
2141
|
Update the settings for a single connection.
|
|
@@ -2092,38 +2143,38 @@ class ConnectionPool:
|
|
|
2092
2143
|
if state:
|
|
2093
2144
|
conn.maintenance_state = state
|
|
2094
2145
|
|
|
2095
|
-
if
|
|
2096
|
-
# update the
|
|
2097
|
-
conn.
|
|
2146
|
+
if update_notification_hash:
|
|
2147
|
+
# update the notification hash only if requested
|
|
2148
|
+
conn.maintenance_notification_hash = maintenance_notification_hash
|
|
2098
2149
|
|
|
2099
2150
|
if host_address is not None:
|
|
2100
2151
|
conn.set_tmp_settings(tmp_host_address=host_address)
|
|
2101
2152
|
|
|
2102
|
-
if
|
|
2103
|
-
conn.set_tmp_settings(
|
|
2153
|
+
if relaxed_timeout is not None:
|
|
2154
|
+
conn.set_tmp_settings(tmp_relaxed_timeout=relaxed_timeout)
|
|
2104
2155
|
|
|
2105
|
-
if
|
|
2156
|
+
if reset_relaxed_timeout or reset_host_address:
|
|
2106
2157
|
conn.reset_tmp_settings(
|
|
2107
2158
|
reset_host_address=reset_host_address,
|
|
2108
|
-
|
|
2159
|
+
reset_relaxed_timeout=reset_relaxed_timeout,
|
|
2109
2160
|
)
|
|
2110
2161
|
|
|
2111
|
-
conn.update_current_socket_timeout(
|
|
2162
|
+
conn.update_current_socket_timeout(relaxed_timeout)
|
|
2112
2163
|
|
|
2113
2164
|
def update_connections_settings(
|
|
2114
2165
|
self,
|
|
2115
2166
|
state: Optional["MaintenanceState"] = None,
|
|
2116
|
-
|
|
2167
|
+
maintenance_notification_hash: Optional[int] = None,
|
|
2117
2168
|
host_address: Optional[str] = None,
|
|
2118
|
-
|
|
2169
|
+
relaxed_timeout: Optional[float] = None,
|
|
2119
2170
|
matching_address: Optional[str] = None,
|
|
2120
|
-
|
|
2171
|
+
matching_notification_hash: Optional[int] = None,
|
|
2121
2172
|
matching_pattern: Literal[
|
|
2122
|
-
"connected_address", "configured_address", "
|
|
2173
|
+
"connected_address", "configured_address", "notification_hash"
|
|
2123
2174
|
] = "connected_address",
|
|
2124
|
-
|
|
2175
|
+
update_notification_hash: bool = False,
|
|
2125
2176
|
reset_host_address: bool = False,
|
|
2126
|
-
|
|
2177
|
+
reset_relaxed_timeout: bool = False,
|
|
2127
2178
|
include_free_connections: bool = True,
|
|
2128
2179
|
):
|
|
2129
2180
|
"""
|
|
@@ -2133,16 +2184,16 @@ class ConnectionPool:
|
|
|
2133
2184
|
This method does not affect the connection kwargs.
|
|
2134
2185
|
|
|
2135
2186
|
:param state: The maintenance state to set for the connection.
|
|
2136
|
-
:param
|
|
2137
|
-
|
|
2187
|
+
:param maintenance_notification_hash: The hash of the maintenance notification
|
|
2188
|
+
to set for the connection.
|
|
2138
2189
|
:param host_address: The host address to set for the connection.
|
|
2139
|
-
:param
|
|
2190
|
+
:param relaxed_timeout: The relaxed timeout to set for the connection.
|
|
2140
2191
|
:param matching_address: The address to match for the connection.
|
|
2141
|
-
:param
|
|
2192
|
+
:param matching_notification_hash: The notification hash to match for the connection.
|
|
2142
2193
|
:param matching_pattern: The pattern to match for the connection.
|
|
2143
|
-
:param
|
|
2194
|
+
:param update_notification_hash: Whether to update the notification hash for the connection.
|
|
2144
2195
|
:param reset_host_address: Whether to reset the host address to the original address.
|
|
2145
|
-
:param
|
|
2196
|
+
:param reset_relaxed_timeout: Whether to reset the relaxed timeout to the original timeout.
|
|
2146
2197
|
:param include_free_connections: Whether to include free/available connections.
|
|
2147
2198
|
"""
|
|
2148
2199
|
with self._lock:
|
|
@@ -2151,17 +2202,17 @@ class ConnectionPool:
|
|
|
2151
2202
|
conn,
|
|
2152
2203
|
matching_pattern,
|
|
2153
2204
|
matching_address,
|
|
2154
|
-
|
|
2205
|
+
matching_notification_hash,
|
|
2155
2206
|
):
|
|
2156
2207
|
self.update_connection_settings(
|
|
2157
2208
|
conn,
|
|
2158
2209
|
state=state,
|
|
2159
|
-
|
|
2210
|
+
maintenance_notification_hash=maintenance_notification_hash,
|
|
2160
2211
|
host_address=host_address,
|
|
2161
|
-
|
|
2162
|
-
|
|
2212
|
+
relaxed_timeout=relaxed_timeout,
|
|
2213
|
+
update_notification_hash=update_notification_hash,
|
|
2163
2214
|
reset_host_address=reset_host_address,
|
|
2164
|
-
|
|
2215
|
+
reset_relaxed_timeout=reset_relaxed_timeout,
|
|
2165
2216
|
)
|
|
2166
2217
|
|
|
2167
2218
|
if include_free_connections:
|
|
@@ -2170,17 +2221,17 @@ class ConnectionPool:
|
|
|
2170
2221
|
conn,
|
|
2171
2222
|
matching_pattern,
|
|
2172
2223
|
matching_address,
|
|
2173
|
-
|
|
2224
|
+
matching_notification_hash,
|
|
2174
2225
|
):
|
|
2175
2226
|
self.update_connection_settings(
|
|
2176
2227
|
conn,
|
|
2177
2228
|
state=state,
|
|
2178
|
-
|
|
2229
|
+
maintenance_notification_hash=maintenance_notification_hash,
|
|
2179
2230
|
host_address=host_address,
|
|
2180
|
-
|
|
2181
|
-
|
|
2231
|
+
relaxed_timeout=relaxed_timeout,
|
|
2232
|
+
update_notification_hash=update_notification_hash,
|
|
2182
2233
|
reset_host_address=reset_host_address,
|
|
2183
|
-
|
|
2234
|
+
reset_relaxed_timeout=reset_relaxed_timeout,
|
|
2184
2235
|
)
|
|
2185
2236
|
|
|
2186
2237
|
def update_connection_kwargs(
|
|
@@ -2472,17 +2523,17 @@ class BlockingConnectionPool(ConnectionPool):
|
|
|
2472
2523
|
def update_connections_settings(
|
|
2473
2524
|
self,
|
|
2474
2525
|
state: Optional["MaintenanceState"] = None,
|
|
2475
|
-
|
|
2476
|
-
|
|
2526
|
+
maintenance_notification_hash: Optional[int] = None,
|
|
2527
|
+
relaxed_timeout: Optional[float] = None,
|
|
2477
2528
|
host_address: Optional[str] = None,
|
|
2478
2529
|
matching_address: Optional[str] = None,
|
|
2479
|
-
|
|
2530
|
+
matching_notification_hash: Optional[int] = None,
|
|
2480
2531
|
matching_pattern: Literal[
|
|
2481
|
-
"connected_address", "configured_address", "
|
|
2532
|
+
"connected_address", "configured_address", "notification_hash"
|
|
2482
2533
|
] = "connected_address",
|
|
2483
|
-
|
|
2534
|
+
update_notification_hash: bool = False,
|
|
2484
2535
|
reset_host_address: bool = False,
|
|
2485
|
-
|
|
2536
|
+
reset_relaxed_timeout: bool = False,
|
|
2486
2537
|
include_free_connections: bool = True,
|
|
2487
2538
|
):
|
|
2488
2539
|
"""
|
|
@@ -2495,17 +2546,17 @@ class BlockingConnectionPool(ConnectionPool):
|
|
|
2495
2546
|
conn,
|
|
2496
2547
|
matching_pattern,
|
|
2497
2548
|
matching_address,
|
|
2498
|
-
|
|
2549
|
+
matching_notification_hash,
|
|
2499
2550
|
):
|
|
2500
2551
|
self.update_connection_settings(
|
|
2501
2552
|
conn,
|
|
2502
2553
|
state=state,
|
|
2503
|
-
|
|
2554
|
+
maintenance_notification_hash=maintenance_notification_hash,
|
|
2504
2555
|
host_address=host_address,
|
|
2505
|
-
|
|
2506
|
-
|
|
2556
|
+
relaxed_timeout=relaxed_timeout,
|
|
2557
|
+
update_notification_hash=update_notification_hash,
|
|
2507
2558
|
reset_host_address=reset_host_address,
|
|
2508
|
-
|
|
2559
|
+
reset_relaxed_timeout=reset_relaxed_timeout,
|
|
2509
2560
|
)
|
|
2510
2561
|
else:
|
|
2511
2562
|
connections_in_queue = {conn for conn in self.pool.queue if conn}
|
|
@@ -2515,17 +2566,17 @@ class BlockingConnectionPool(ConnectionPool):
|
|
|
2515
2566
|
conn,
|
|
2516
2567
|
matching_pattern,
|
|
2517
2568
|
matching_address,
|
|
2518
|
-
|
|
2569
|
+
matching_notification_hash,
|
|
2519
2570
|
):
|
|
2520
2571
|
self.update_connection_settings(
|
|
2521
2572
|
conn,
|
|
2522
2573
|
state=state,
|
|
2523
|
-
|
|
2574
|
+
maintenance_notification_hash=maintenance_notification_hash,
|
|
2524
2575
|
host_address=host_address,
|
|
2525
|
-
|
|
2526
|
-
|
|
2576
|
+
relaxed_timeout=relaxed_timeout,
|
|
2577
|
+
update_notification_hash=update_notification_hash,
|
|
2527
2578
|
reset_host_address=reset_host_address,
|
|
2528
|
-
|
|
2579
|
+
reset_relaxed_timeout=reset_relaxed_timeout,
|
|
2529
2580
|
)
|
|
2530
2581
|
|
|
2531
2582
|
def update_active_connections_for_reconnect(
|
|
@@ -2569,26 +2620,30 @@ class BlockingConnectionPool(ConnectionPool):
|
|
|
2569
2620
|
):
|
|
2570
2621
|
conn.disconnect()
|
|
2571
2622
|
|
|
2572
|
-
def
|
|
2573
|
-
self,
|
|
2623
|
+
def _update_maint_notifications_config_for_connections(
|
|
2624
|
+
self, maint_notifications_config
|
|
2574
2625
|
):
|
|
2575
2626
|
for conn in tuple(self._connections):
|
|
2576
|
-
conn.
|
|
2627
|
+
conn.maint_notifications_config = maint_notifications_config
|
|
2577
2628
|
|
|
2578
|
-
def
|
|
2579
|
-
self,
|
|
2629
|
+
def _update_maint_notifications_configs_for_connections(
|
|
2630
|
+
self, maint_notifications_pool_handler
|
|
2580
2631
|
):
|
|
2581
|
-
"""Update the maintenance
|
|
2632
|
+
"""Update the maintenance notifications config for all connections in the pool."""
|
|
2582
2633
|
with self._lock:
|
|
2583
2634
|
for conn in tuple(self._connections):
|
|
2584
|
-
conn.
|
|
2585
|
-
|
|
2635
|
+
conn.set_maint_notifications_pool_handler(
|
|
2636
|
+
maint_notifications_pool_handler
|
|
2637
|
+
)
|
|
2638
|
+
conn.maint_notifications_config = (
|
|
2639
|
+
maint_notifications_pool_handler.config
|
|
2640
|
+
)
|
|
2586
2641
|
|
|
2587
2642
|
def set_in_maintenance(self, in_maintenance: bool):
|
|
2588
2643
|
"""
|
|
2589
2644
|
Sets a flag that this Blocking ConnectionPool is in maintenance mode.
|
|
2590
2645
|
|
|
2591
2646
|
This is used to prevent new connections from being created while we are in maintenance mode.
|
|
2592
|
-
The pool will be in maintenance mode only when we are processing a MOVING
|
|
2647
|
+
The pool will be in maintenance mode only when we are processing a MOVING notification.
|
|
2593
2648
|
"""
|
|
2594
2649
|
self._in_maintenance = in_maintenance
|