GuglielmoTor commited on
Commit
f813a3c
·
verified ·
1 Parent(s): c1843e2

Create utils/retry_mechanism.py

Browse files
insight_and_tasks/utils/retry_mechanism.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # utils/retry_mechanism.py
2
+ import time
3
+ import logging
4
+ from typing import Callable, Any, Tuple
5
+
6
+ # Configure logger for this module
7
+ logger = logging.getLogger(__name__)
8
+
9
+ class RetryMechanism:
10
+ """External retry mechanism with exponential backoff"""
11
+
12
+ @staticmethod
13
+ def retry_with_backoff(
14
+ func: Callable,
15
+ max_retries: int = 3,
16
+ base_delay: float = 1.0,
17
+ exceptions: Tuple[type[Exception], ...] = (Exception,) # More specific type hint
18
+ ) -> Any:
19
+ """
20
+ Retries a function call with exponential backoff.
21
+
22
+ Args:
23
+ func: The function to call.
24
+ max_retries: Maximum number of retries.
25
+ base_delay: Base delay in seconds for backoff.
26
+ exceptions: A tuple of exception types to catch and retry on.
27
+
28
+ Returns:
29
+ The result of the function call if successful.
30
+
31
+ Raises:
32
+ The last exception encountered if all retries fail.
33
+ """
34
+ last_exception = None
35
+ current_delay = base_delay
36
+
37
+ for attempt in range(max_retries + 1): # +1 for initial attempt
38
+ try:
39
+ logger.info(f"Attempt {attempt + 1}/{max_retries + 1} for function {func.__name__}")
40
+ result = func()
41
+ if attempt > 0: # Log if a retry was successful
42
+ logger.info(f"Function {func.__name__} succeeded on attempt {attempt + 1}")
43
+ return result
44
+ except exceptions as e:
45
+ last_exception = e
46
+ logger.warning(f"Attempt {attempt + 1} for {func.__name__} failed: {str(e)}")
47
+
48
+ if attempt < max_retries:
49
+ logger.info(f"Waiting {current_delay:.2f} seconds before retrying {func.__name__}...")
50
+ time.sleep(current_delay)
51
+ current_delay *= 2 # Exponential backoff
52
+ else:
53
+ logger.error(f"All {max_retries + 1} attempts for {func.__name__} failed.")
54
+
55
+ # If loop finishes, all retries failed, raise the last exception
56
+ if last_exception is not None:
57
+ raise last_exception
58
+ else:
59
+ # This case should ideally not be reached if func always raises on failure
60
+ # or returns successfully. Added for completeness.
61
+ raise RuntimeError(f"Function {func.__name__} failed after all retries without a specific exception.")