Practical Example: Retrying Connections with a Limit
๐ท๏ธ Loops and Iteration / The While Loop
๐ง Context Introduction
In real-world automation and system management, connections to services, databases, or APIs often fail temporarily due to network issues, service restarts, or resource contention. A while loop is perfect for retrying these connections a limited number of times before giving up. This pattern prevents your script from hanging forever and gives you control over failure handling.
โ๏ธ What We Are Building
We want to simulate connecting to a service that may be temporarily unavailable. Our script will:
- Attempt to connect up to 5 times
- Wait 2 seconds between each attempt
- Stop early if the connection succeeds
- Print a clear success or failure message
๐ ๏ธ The Core Logic Explained
- A counter variable tracks how many attempts have been made
- A while loop runs as long as attempts remain and the connection has not succeeded
- Inside the loop, we attempt the connection
- If it fails, we increment the counter and wait
- If it succeeds, we break out of the loop
- After the loop, we check whether we succeeded or exhausted all attempts
๐ Comparison: While Loop vs. For Loop for Retries
| Feature | While Loop | For Loop |
|---|---|---|
| Flexibility | Can stop early based on any condition | Runs a fixed number of times |
| Readability | Very clear for "keep trying until" logic | Good for known attempt counts |
| Control | Easy to add complex exit conditions | Requires extra logic for early exit |
| Common Use | Retry with dynamic conditions | Simple fixed retry counts |
๐ต๏ธ Step-by-Step Breakdown
1. Set up your retry parameters - Define a max_attempts variable (e.g., 5) - Define a wait_time variable (e.g., 2 seconds) - Create a counter starting at 0 - Create a success flag set to False
2. Write the while loop condition - The loop runs while counter < max_attempts AND success is False
3. Inside the loop - Increment the counter by 1 - Print the current attempt number - Simulate the connection attempt (this is where your real logic goes) - If the connection succeeds, set success = True and print a success message - If it fails, print a failure message and wait for the defined wait time
4. After the loop - Check the success flag - If True, print a final success confirmation - If False, print a failure message indicating all attempts were exhausted
๐ Example Script Flow (No Code Blocks)
Step 1: Define variables - Set max_attempts = 5 - Set wait_time = 2 - Set attempt = 0 - Set connected = False
Step 2: While loop condition - While attempt < max_attempts and connected is False
Step 3: Inside the loop - Increase attempt by 1 - Print: "Attempt number: [attempt]" - Simulate connection (replace with real logic) - If connection succeeds: - Set connected = True - Print: "Connection successful on attempt [attempt]" - Else: - Print: "Connection failed on attempt [attempt]" - Wait for wait_time seconds
Step 4: After the loop - If connected is True: - Print: "Successfully connected to the service." - Else: - Print: "Failed to connect after [max_attempts] attempts."
๐งช Expected Behavior
- If the service becomes available on attempt 3: The loop will stop early, and you will see success messages for attempt 3 only
- If the service never becomes available: The loop will run all 5 attempts, then print the failure message
- If the service is available immediately: The loop will run only once and exit
๐ฏ Key Takeaways for Engineers
- Always set a maximum retry limit to prevent infinite loops
- Use a success flag to cleanly exit the loop when the goal is achieved
- Add a delay between retries to avoid overwhelming the target service
- Print clear status messages for debugging and monitoring
- This pattern works for any resource โ databases, APIs, network sockets, file locks, or cloud services
๐ Real-World Applications
- Database connection retries after a server restart
- API calls during rate limiting or temporary outages
- Network socket connections to unreliable services
- File lock acquisition in shared storage systems
- Cloud resource provisioning waiting for a resource to become active
๐ก Pro Tip
For more advanced retry logic, consider adding: - Exponential backoff (increase wait time after each failure) - Jitter (randomize wait time slightly to avoid thundering herd) - Different failure handling for different error types - Logging to a file for post-mortem analysis
Next in series: Practical Example: Menu-Driven Scripts with While Loops
This pattern uses a while loop to repeatedly attempt an operation until it succeeds or a maximum number of tries is reached.
๐ง Example 1: Simple retry counter
This shows a basic while loop that counts down attempts.
attempts = 0
max_attempts = 3
while attempts < max_attempts:
print(f"Attempt {attempts + 1}")
attempts = attempts + 1
print("Done trying")
๐ค Output: Attempt 1 Attempt 2 Attempt 3 Done trying
๐ง Example 2: Retry with a simulated failure
This demonstrates a loop that keeps trying until a condition is met or attempts run out.
attempts = 0
max_attempts = 3
success = False
while attempts < max_attempts and not success:
print(f"Trying connection... attempt {attempts + 1}")
attempts = attempts + 1
if attempts == 3:
success = True
if success:
print("Connection established")
else:
print("Connection failed after all attempts")
๐ค Output: Trying connection... attempt 1 Trying connection... attempt 2 Trying connection... attempt 3 Connection established
๐ง Example 3: Retry with a delay between attempts
This shows how to add a small pause between retry attempts using time.sleep().
import time
attempts = 0
max_attempts = 3
success = False
while attempts < max_attempts and not success:
attempts = attempts + 1
print(f"Attempt {attempts}: connecting to server...")
time.sleep(1)
if attempts == 2:
success = True
if success:
print(f"Connected on attempt {attempts}")
else:
print("All attempts failed")
๐ค Output: Attempt 1: connecting to server... Attempt 2: connecting to server... Connected on attempt 2
๐ง Example 4: Retry with a random failure simulation
This demonstrates a more realistic scenario where each attempt might randomly succeed or fail.
import random
import time
attempts = 0
max_attempts = 5
success = False
while attempts < max_attempts and not success:
attempts = attempts + 1
print(f"Attempt {attempts}: sending request...")
time.sleep(0.5)
if random.randint(1, 10) > 7:
success = True
print("Response received")
else:
print("Timeout, retrying...")
if success:
print(f"Operation succeeded on attempt {attempts}")
else:
print("Operation failed after 5 attempts")
๐ค Output: Attempt 1: sending request... Timeout, retrying... Attempt 2: sending request... Response received Operation succeeded on attempt 2
๐ง Example 5: Retry with exponential backoff
This shows a practical pattern where wait time increases between each retry attempt.
import time
attempts = 0
max_attempts = 4
success = False
wait_time = 1
while attempts < max_attempts and not success:
attempts = attempts + 1
print(f"Attempt {attempts}: connecting to database...")
if attempts == 3:
success = True
print("Database connected")
else:
print(f"Connection failed, waiting {wait_time} second(s)...")
time.sleep(wait_time)
wait_time = wait_time * 2
if success:
print(f"Connected on attempt {attempts}")
else:
print("All retry attempts exhausted")
๐ค Output: Attempt 1: connecting to database... Connection failed, waiting 1 second(s)... Attempt 2: connecting to database... Connection failed, waiting 2 second(s)... Attempt 3: connecting to database... Database connected Connected on attempt 3
Comparison Table
| Feature | Basic Counter | Simulated Failure | With Delay | Random Failure | Exponential Backoff |
|---|---|---|---|---|---|
| Max attempts | 3 | 3 | 3 | 5 | 4 |
| Uses time.sleep() | No | No | Yes | Yes | Yes |
| Success condition | Always last attempt | Fixed attempt number | Fixed attempt number | Random chance | Fixed attempt number |
| Wait between retries | None | None | 1 second | 0.5 seconds | Doubles each time |
๐ง Context Introduction
In real-world automation and system management, connections to services, databases, or APIs often fail temporarily due to network issues, service restarts, or resource contention. A while loop is perfect for retrying these connections a limited number of times before giving up. This pattern prevents your script from hanging forever and gives you control over failure handling.
โ๏ธ What We Are Building
We want to simulate connecting to a service that may be temporarily unavailable. Our script will:
- Attempt to connect up to 5 times
- Wait 2 seconds between each attempt
- Stop early if the connection succeeds
- Print a clear success or failure message
๐ ๏ธ The Core Logic Explained
- A counter variable tracks how many attempts have been made
- A while loop runs as long as attempts remain and the connection has not succeeded
- Inside the loop, we attempt the connection
- If it fails, we increment the counter and wait
- If it succeeds, we break out of the loop
- After the loop, we check whether we succeeded or exhausted all attempts
๐ Comparison: While Loop vs. For Loop for Retries
| Feature | While Loop | For Loop |
|---|---|---|
| Flexibility | Can stop early based on any condition | Runs a fixed number of times |
| Readability | Very clear for "keep trying until" logic | Good for known attempt counts |
| Control | Easy to add complex exit conditions | Requires extra logic for early exit |
| Common Use | Retry with dynamic conditions | Simple fixed retry counts |
๐ต๏ธ Step-by-Step Breakdown
1. Set up your retry parameters - Define a max_attempts variable (e.g., 5) - Define a wait_time variable (e.g., 2 seconds) - Create a counter starting at 0 - Create a success flag set to False
2. Write the while loop condition - The loop runs while counter < max_attempts AND success is False
3. Inside the loop - Increment the counter by 1 - Print the current attempt number - Simulate the connection attempt (this is where your real logic goes) - If the connection succeeds, set success = True and print a success message - If it fails, print a failure message and wait for the defined wait time
4. After the loop - Check the success flag - If True, print a final success confirmation - If False, print a failure message indicating all attempts were exhausted
๐ Example Script Flow (No Code Blocks)
Step 1: Define variables - Set max_attempts = 5 - Set wait_time = 2 - Set attempt = 0 - Set connected = False
Step 2: While loop condition - While attempt < max_attempts and connected is False
Step 3: Inside the loop - Increase attempt by 1 - Print: "Attempt number: [attempt]" - Simulate connection (replace with real logic) - If connection succeeds: - Set connected = True - Print: "Connection successful on attempt [attempt]" - Else: - Print: "Connection failed on attempt [attempt]" - Wait for wait_time seconds
Step 4: After the loop - If connected is True: - Print: "Successfully connected to the service." - Else: - Print: "Failed to connect after [max_attempts] attempts."
๐งช Expected Behavior
- If the service becomes available on attempt 3: The loop will stop early, and you will see success messages for attempt 3 only
- If the service never becomes available: The loop will run all 5 attempts, then print the failure message
- If the service is available immediately: The loop will run only once and exit
๐ฏ Key Takeaways for Engineers
- Always set a maximum retry limit to prevent infinite loops
- Use a success flag to cleanly exit the loop when the goal is achieved
- Add a delay between retries to avoid overwhelming the target service
- Print clear status messages for debugging and monitoring
- This pattern works for any resource โ databases, APIs, network sockets, file locks, or cloud services
๐ Real-World Applications
- Database connection retries after a server restart
- API calls during rate limiting or temporary outages
- Network socket connections to unreliable services
- File lock acquisition in shared storage systems
- Cloud resource provisioning waiting for a resource to become active
๐ก Pro Tip
For more advanced retry logic, consider adding: - Exponential backoff (increase wait time after each failure) - Jitter (randomize wait time slightly to avoid thundering herd) - Different failure handling for different error types - Logging to a file for post-mortem analysis
Next in series: Practical Example: Menu-Driven Scripts with While Loops
Interactive Views
You are currently in ๐ All-in-One mode. Use the tabs at the top to switch to ๐ Theory Only or ๐ป Code Only views.
This pattern uses a while loop to repeatedly attempt an operation until it succeeds or a maximum number of tries is reached.
๐ง Example 1: Simple retry counter
This shows a basic while loop that counts down attempts.
attempts = 0
max_attempts = 3
while attempts < max_attempts:
print(f"Attempt {attempts + 1}")
attempts = attempts + 1
print("Done trying")
๐ค Output: Attempt 1 Attempt 2 Attempt 3 Done trying
๐ง Example 2: Retry with a simulated failure
This demonstrates a loop that keeps trying until a condition is met or attempts run out.
attempts = 0
max_attempts = 3
success = False
while attempts < max_attempts and not success:
print(f"Trying connection... attempt {attempts + 1}")
attempts = attempts + 1
if attempts == 3:
success = True
if success:
print("Connection established")
else:
print("Connection failed after all attempts")
๐ค Output: Trying connection... attempt 1 Trying connection... attempt 2 Trying connection... attempt 3 Connection established
๐ง Example 3: Retry with a delay between attempts
This shows how to add a small pause between retry attempts using time.sleep().
import time
attempts = 0
max_attempts = 3
success = False
while attempts < max_attempts and not success:
attempts = attempts + 1
print(f"Attempt {attempts}: connecting to server...")
time.sleep(1)
if attempts == 2:
success = True
if success:
print(f"Connected on attempt {attempts}")
else:
print("All attempts failed")
๐ค Output: Attempt 1: connecting to server... Attempt 2: connecting to server... Connected on attempt 2
๐ง Example 4: Retry with a random failure simulation
This demonstrates a more realistic scenario where each attempt might randomly succeed or fail.
import random
import time
attempts = 0
max_attempts = 5
success = False
while attempts < max_attempts and not success:
attempts = attempts + 1
print(f"Attempt {attempts}: sending request...")
time.sleep(0.5)
if random.randint(1, 10) > 7:
success = True
print("Response received")
else:
print("Timeout, retrying...")
if success:
print(f"Operation succeeded on attempt {attempts}")
else:
print("Operation failed after 5 attempts")
๐ค Output: Attempt 1: sending request... Timeout, retrying... Attempt 2: sending request... Response received Operation succeeded on attempt 2
๐ง Example 5: Retry with exponential backoff
This shows a practical pattern where wait time increases between each retry attempt.
import time
attempts = 0
max_attempts = 4
success = False
wait_time = 1
while attempts < max_attempts and not success:
attempts = attempts + 1
print(f"Attempt {attempts}: connecting to database...")
if attempts == 3:
success = True
print("Database connected")
else:
print(f"Connection failed, waiting {wait_time} second(s)...")
time.sleep(wait_time)
wait_time = wait_time * 2
if success:
print(f"Connected on attempt {attempts}")
else:
print("All retry attempts exhausted")
๐ค Output: Attempt 1: connecting to database... Connection failed, waiting 1 second(s)... Attempt 2: connecting to database... Connection failed, waiting 2 second(s)... Attempt 3: connecting to database... Database connected Connected on attempt 3
Comparison Table
| Feature | Basic Counter | Simulated Failure | With Delay | Random Failure | Exponential Backoff |
|---|---|---|---|---|---|
| Max attempts | 3 | 3 | 3 | 5 | 4 |
| Uses time.sleep() | No | No | Yes | Yes | Yes |
| Success condition | Always last attempt | Fixed attempt number | Fixed attempt number | Random chance | Fixed attempt number |
| Wait between retries | None | None | 1 second | 0.5 seconds | Doubles each time |