Skip to content

Conversation

@Harsh-Microsoft
Copy link
Contributor

Purpose

This pull request introduces several changes across different parts of the codebase, focusing on improving retry mechanisms, enhancing resource uniqueness, and optimizing configurations. Below are the most important changes grouped by theme:

Retry Mechanisms and Error Handling:

  • Added a retry mechanism with exponential backoff to the get_connection function in src/App/backend/services/sqldb_service.py, allowing up to 5 retries with increasing delays when connecting to the database fails. [1] [2]
  • Implemented a retry mechanism with a single retry and a 5-second delay in the getUsers function in src/App/frontend/src/api/api.ts to handle transient errors during API calls.

Resource Uniqueness:

  • Updated the uniqueId variable in infra/main.bicep to include resourceGroup().name in its calculation, ensuring more unique resource identifiers.

Configuration Changes:

  • Reduced the number of workers in the CMD instruction of src/App/WebApp.Dockerfile from 4 to 1, likely to optimize resource usage in the containerized environment.

Codebase Enhancements:

  • Added a sleep utility function to src/App/frontend/src/api/api.ts for implementing delays in retry logic.
  • Imported the time module in src/App/backend/services/sqldb_service.py to support the retry mechanism with exponential backoff.

Does this introduce a breaking change?

  • Yes
  • No

Golden Path Validation

  • I have tested the primary workflows (the "golden path") to ensure they function correctly without errors.

Deployment Validation

  • I have validated the deployment process successfully and all services are running as expected with this change.

What to Check

Verify that the following are valid

  • ...

Other Information

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances system reliability by implementing retry mechanisms for database connections and API calls, while also improving resource uniqueness and optimizing containerized deployment configuration.

  • Added exponential backoff retry logic for SQL database connections with up to 5 attempts
  • Implemented retry mechanism for frontend API calls with timeout and error handling
  • Enhanced resource uniqueness by including resource group name in identifier calculation
  • Reduced Docker container workers from 4 to 1 for optimized resource usage

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/App/backend/services/sqldb_service.py Added retry logic with exponential backoff for database connections
src/App/frontend/src/api/api.ts Implemented retry mechanism and timeout for user API calls
src/App/WebApp.Dockerfile Reduced uvicorn workers from 4 to 1
infra/main.bicep Enhanced uniqueId calculation to include resource group name

Comment on lines +63 to 80
try:
conn = pyodbc.connect(
f"DRIVER={driver};SERVER={server};DATABASE={database};UID={username};PWD={password}",
timeout=5,
)
logging.info("Connected using Username & Password")
return conn
except pyodbc.Error as e:
logging.error(f"Failed with Username & Password: {str(e)}")

if attempt < max_retries - 1:
logging.info(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
retry_delay *= 2 # Exponential backoff
else:
raise e


Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested try-catch blocks create complex control flow that's difficult to follow. Consider extracting the password-based connection attempt into a separate function or restructuring the retry logic to handle both authentication methods in a cleaner way.

Suggested change
try:
conn = pyodbc.connect(
f"DRIVER={driver};SERVER={server};DATABASE={database};UID={username};PWD={password}",
timeout=5,
)
logging.info("Connected using Username & Password")
return conn
except pyodbc.Error as e:
logging.error(f"Failed with Username & Password: {str(e)}")
if attempt < max_retries - 1:
logging.info(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
retry_delay *= 2 # Exponential backoff
else:
raise e
try:
conn = connect_with_password()
logging.info("Connected using Username & Password")
return conn
except pyodbc.Error as e:
logging.error(f"Failed with Username & Password: {str(e)}")
if attempt < max_retries - 1:
logging.info(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
retry_delay *= 2 # Exponential backoff
else:
raise e

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +78
except pyodbc.Error as e:
logging.error(f"Failed with Username & Password: {str(e)}")

if attempt < max_retries - 1:
logging.info(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
retry_delay *= 2 # Exponential backoff
else:
raise e
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception being raised here (e) is from the inner try-catch block (Username & Password authentication failure), but if the Default Credential also failed, that error information is lost. Consider raising a more comprehensive error that includes both failure modes or the original Default Credential error.

Suggested change
except pyodbc.Error as e:
logging.error(f"Failed with Username & Password: {str(e)}")
if attempt < max_retries - 1:
logging.info(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
retry_delay *= 2 # Exponential backoff
else:
raise e
except pyodbc.Error as username_password_error:
logging.error(f"Failed with Username & Password: {str(username_password_error)}")
if attempt < max_retries - 1:
logging.info(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
retry_delay *= 2 # Exponential backoff
else:
raise RuntimeError(
f"Connection failed after multiple attempts. "
f"Default Credential error: {str(default_credential_error)}; "
f"Username & Password error: {str(username_password_error)}"
)

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +62
if (attempt < maxRetries &&
error instanceof Error) {
Copy link

Copilot AI Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The retry logic only retries on Error instances, but AbortSignal.timeout errors may not always be Error instances. Consider checking for specific error types (like AbortError for timeouts) or removing the instanceof Error check to retry on all errors.

Suggested change
if (attempt < maxRetries &&
error instanceof Error) {
if (attempt < maxRetries) {

Copilot uses AI. Check for mistakes.
* working agent management

* fix pylint

* fix test cases

* fix pylint

---------

Co-authored-by: Shreyas-Microsoft <v-swaikar@microsft.com>
Rafi-Microsoft and others added 3 commits July 31, 2025 16:51
@Prajwal-Microsoft Prajwal-Microsoft merged commit e558c65 into main Jul 31, 2025
22 of 26 checks passed
@github-actions
Copy link

🎉 This PR is included in version 1.8.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants