15
15
from .address_helper import validate_address
16
16
from .consumer import Consumer
17
17
from .entities import RecoveryConfiguration , StreamOptions
18
- from .exceptions import ArgumentOutOfRangeException
18
+ from .exceptions import (
19
+ ArgumentOutOfRangeException ,
20
+ ValidationCodeException ,
21
+ )
19
22
from .management import Management
20
23
from .publisher import Publisher
21
24
from .qpid .proton ._exceptions import ConnectionException
@@ -57,7 +60,7 @@ def __init__(
57
60
ssl_context : Union [
58
61
PosixSslConfigurationContext , WinSslConfigurationContext , None
59
62
] = None ,
60
- recovery_configuration : Optional [ RecoveryConfiguration ] = None ,
63
+ recovery_configuration : RecoveryConfiguration = RecoveryConfiguration () ,
61
64
):
62
65
"""
63
66
Initialize a new Connection instance.
@@ -84,16 +87,55 @@ def __init__(
84
87
PosixSslConfigurationContext , WinSslConfigurationContext , None
85
88
] = ssl_context
86
89
self ._managements : list [Management ] = []
87
- self ._recovery_configuration = recovery_configuration
90
+ self ._recovery_configuration : RecoveryConfiguration = recovery_configuration
88
91
self ._ssl_domain = None
89
92
self ._connections = [] # type: ignore
90
93
self ._index : int = - 1
91
94
self ._publishers : list [Publisher ] = []
92
95
self ._consumers : list [Consumer ] = []
93
96
97
+ # Some recovery_configuration validation
98
+ if recovery_configuration .back_off_reconnect_interval < timedelta (seconds = 1 ):
99
+ raise ValidationCodeException (
100
+ "back_off_reconnect_interval must be > 1 second"
101
+ )
102
+
103
+ if recovery_configuration .MaxReconnectAttempts < 1 :
104
+ raise ValidationCodeException ("MaxReconnectAttempts must be at least 1" )
105
+
94
106
def _set_environment_connection_list (self , connections : []): # type: ignore
95
107
self ._connections = connections
96
108
109
+ def _open_connections (self , reconnect_handlers : bool = False ) -> None :
110
+
111
+ if self ._recovery_configuration .active_recovery is False :
112
+ self ._conn = BlockingConnection (
113
+ url = self ._addr ,
114
+ urls = self ._addrs ,
115
+ ssl_domain = self ._ssl_domain ,
116
+ )
117
+ else :
118
+ self ._conn = BlockingConnection (
119
+ url = self ._addr ,
120
+ urls = self ._addrs ,
121
+ ssl_domain = self ._ssl_domain ,
122
+ on_disconnection_handler = self ._on_disconnection ,
123
+ )
124
+
125
+ if reconnect_handlers is True :
126
+
127
+ for i , management in enumerate (self ._managements ):
128
+ # Update the broken connection and sender in the management
129
+ self ._managements [i ]._update_connection (self ._conn )
130
+
131
+ for i , publisher in enumerate (self ._publishers ):
132
+ # Update the broken connection and sender in the publisher
133
+ self ._publishers [i ]._update_connection (self ._conn )
134
+
135
+ for i , consumer in enumerate (self ._consumers ):
136
+ # Update the broken connection and sender in the consumer
137
+ self ._consumers [i ]._update_connection (self ._conn )
138
+
97
139
def dial (self ) -> None :
98
140
"""
99
141
Establish a connection to the AMQP server.
@@ -148,24 +190,7 @@ def dial(self) -> None:
148
190
password ,
149
191
)
150
192
151
- if (
152
- self ._recovery_configuration is None
153
- or self ._recovery_configuration .active_recovery is False
154
- ):
155
- self ._conn = BlockingConnection (
156
- url = self ._addr ,
157
- urls = self ._addrs ,
158
- ssl_domain = self ._ssl_domain ,
159
- )
160
- else :
161
- self ._conn = BlockingConnection (
162
- url = self ._addr ,
163
- urls = self ._addrs ,
164
- ssl_domain = self ._ssl_domain ,
165
- on_disconnection_handler = self ._on_disconnection ,
166
- )
167
-
168
- # self._open()
193
+ self ._open_connections ()
169
194
logger .debug ("Connection to the server established" )
170
195
171
196
def _win_store_to_cert (
@@ -282,10 +307,10 @@ def _on_disconnection(self) -> None:
282
307
if self in self ._connections :
283
308
self ._connections .remove (self )
284
309
285
- base_delay = self ._recovery_configuration .back_off_reconnect_interval # type: ignore
310
+ base_delay = self ._recovery_configuration .back_off_reconnect_interval
286
311
max_delay = timedelta (minutes = 1 )
287
312
288
- for attempt in range (self ._recovery_configuration .MaxReconnectAttempts ): # type: ignore
313
+ for attempt in range (self ._recovery_configuration .MaxReconnectAttempts ):
289
314
290
315
logger .debug ("attempting a reconnection" )
291
316
jitter = timedelta (milliseconds = random .randint (0 , 500 ))
@@ -297,26 +322,10 @@ def _on_disconnection(self) -> None:
297
322
time .sleep (delay .total_seconds ())
298
323
299
324
try :
300
- self ._conn = BlockingConnection (
301
- url = self ._addr ,
302
- urls = self ._addrs ,
303
- ssl_domain = self ._ssl_domain ,
304
- on_disconnection_handler = self ._on_disconnection ,
305
- )
306
-
307
- self ._connections .append (self )
308
325
309
- for i , management in enumerate (self ._managements ):
310
- # Update the broken connection and sender in the management
311
- self ._managements [i ]._update_connection (self ._conn )
326
+ self ._open_connections (reconnect_handlers = True )
312
327
313
- for i , publisher in enumerate (self ._publishers ):
314
- # Update the broken connection and sender in the publisher
315
- self ._publishers [i ]._update_connection (self ._conn )
316
-
317
- for i , consumer in enumerate (self ._consumers ):
318
- # Update the broken connection and sender in the consumer
319
- self ._consumers [i ]._update_connection (self ._conn )
328
+ self ._connections .append (self )
320
329
321
330
except ConnectionException as e :
322
331
base_delay *= 2
@@ -328,7 +337,7 @@ def _on_disconnection(self) -> None:
328
337
str (e ),
329
338
)
330
339
# maximum attempts reached without establishing a connection
331
- if attempt == self ._recovery_configuration .MaxReconnectAttempts - 1 : # type: ignore
340
+ if attempt == self ._recovery_configuration .MaxReconnectAttempts - 1 :
332
341
logger .debug ("Not able to reconnect" )
333
342
raise ConnectionException
334
343
else :
0 commit comments