1919SQL_TRANSIENT_EXCEPTIONS = (TimeoutError , ConnectionError , * ADDITIONAL_TRANSIENT_ERRORS )
2020
2121
22- class ExceptionsWaitStrategy (WaitStrategy ):
22+ class ConnectWaitStrategy (WaitStrategy ):
2323 """
24- Generic wait strategy that retries a callable until it succeeds or times out.
24+ Wait strategy that retries a container's _connect method until it succeeds or times out.
2525
26- This strategy can be used with any container method that needs retry logic
27- for handling transient errors . It calls the provided callable repeatedly
28- until it succeeds or the timeout is reached .
26+ This strategy assumes the container has a _connect method and will call it repeatedly
27+ until it succeeds or the timeout is reached . It handles transient connection errors
28+ and provides appropriate retry logic for database connectivity testing .
2929 """
3030
31- def __init__ (self , callable_func : callable , transient_exceptions : Optional [tuple ] = None ):
31+ def __init__ (self , transient_exceptions : Optional [tuple ] = None ):
3232 super ().__init__ ()
33- self .callable_func = callable_func
3433 self .transient_exceptions = transient_exceptions or (TimeoutError , ConnectionError )
3534
3635 def wait_until_ready (self , container : WaitStrategyTarget ) -> None :
3736 """
38- Execute the callable with retry logic until it succeeds or times out.
37+ Execute the container's _connect method with retry logic until it succeeds or times out.
38+
39+ Args:
40+ container: The container that must have a _connect method
3941
4042 Raises:
41- TimeoutError: If callable fails after timeout
42- Exception: Any non-transient errors from the callable
43+ TimeoutError: If _connect fails after timeout
44+ AttributeError: If container doesn't have _connect method
45+ Exception: Any non-transient errors from _connect
4346 """
4447 import time
4548
49+ if not hasattr (container , "_connect" ):
50+ raise AttributeError (f"Container { container } must have a _connect method" )
51+
4652 start_time = time .time ()
4753
4854 while True :
4955 if time .time () - start_time > self ._startup_timeout :
5056 raise TimeoutError (
51- f"Callable failed after { self ._startup_timeout } s timeout. "
52- f"Hint: Check if the container is ready and the operation can succeed ."
57+ f"Container _connect failed after { self ._startup_timeout } s timeout. "
58+ f"Hint: Check if the container is ready and the database is accessible ."
5359 )
5460
5561 try :
56- self . callable_func ()
62+ container . _connect ()
5763 return
5864 except self .transient_exceptions as e :
59- logger .debug (f"Callable attempt failed: { e } , retrying in { self ._poll_interval } s..." )
65+ logger .debug (f"Connection attempt failed: { e } , retrying in { self ._poll_interval } s..." )
6066 except Exception as e :
61- logger .error (f"Callable failed with non-transient error: { e } " )
67+ logger .error (f"Connection failed with non-transient error: { e } " )
6268 raise
6369
6470 time .sleep (self ._poll_interval )
@@ -70,15 +76,15 @@ class SqlContainer(DockerContainer):
7076
7177 This class can serve as a base for database-specific container implementations.
7278 It provides connection management, URL construction, and basic lifecycle methods.
73- Database connection readiness is automatically handled by ExceptionsWaitStrategy .
79+ Database connection readiness is automatically handled by ConnectWaitStrategy .
7480 """
7581
7682 def _connect (self ) -> None :
7783 """
7884 Test database connectivity using SQLAlchemy.
7985
8086 This method performs a single connection test without retry logic.
81- Retry logic is handled by the DatabaseConnectionWaitStrategy .
87+ Retry logic is handled by the ConnectWaitStrategy .
8288
8389 Raises:
8490 ImportError: If SQLAlchemy is not installed
@@ -184,7 +190,7 @@ def start(self) -> "SqlContainer":
184190
185191 try :
186192 self ._configure ()
187- self .waiting_for (ExceptionsWaitStrategy ( self . _connect , SQL_TRANSIENT_EXCEPTIONS ))
193+ self .waiting_for (ConnectWaitStrategy ( SQL_TRANSIENT_EXCEPTIONS ))
188194 super ().start ()
189195 self ._transfer_seed ()
190196 logger .info ("Database container started successfully" )
0 commit comments