Skip to content

feat(medium): Refactor Bluetooth Connection Retry Logic#9134

Merged
arii merged 32 commits intoleaderfrom
refactor-bluetooth-retry-logic-3626867553841703440
Feb 22, 2026
Merged

feat(medium): Refactor Bluetooth Connection Retry Logic#9134
arii merged 32 commits intoleaderfrom
refactor-bluetooth-retry-logic-3626867553841703440

Conversation

@arii
Copy link
Owner

@arii arii commented Feb 22, 2026

Description

Refactored Bluetooth connection retry logic in useBluetoothHRM.ts to improve resilience and maintainability. Implemented a unified linear backoff strategy with jitter, simplified AbortController management, and removed nested retry loops. Updated constants and unit tests to align with these changes.

Fixes #8872

Change Type: 🏗️ Refactoring (code change that neither fixes bug nor adds feature)

Related Issues

Closes #8872

Testing

Updated unit tests to align with these changes.

Original PR Body

Refactored Bluetooth connection retry logic in useBluetoothHRM.ts to improve resilience and maintainability. Implemented a unified linear backoff strategy with jitter, simplified AbortController management, and removed nested retry loops. Updated constants and unit tests to align with these changes.

Fixes #8872


PR created automatically by Jules for task 3626867553841703440 started by @arii

… strategy

This commit refactors the `useBluetoothHRM.ts` hook and associated constants
to improve resilience and maintainability of Bluetooth connections.

Key changes:
- Unified backoff strategy: Consolidated reconnection timing constants into a single `getBackoffDelay` utility implementing linear backoff with jitter.
- Reduced cyclomatic complexity: Removed the nested `while` loop in `connectToGatt` and centralized retry logic in the `reconnect` function.
- Streamlined AbortController management: Simplified `abortControllerRef` usage to ensure clean connection attempts.
- Updated defaults: Set `BLUETOOTH_MAX_RECONNECT_ATTEMPTS` to 8 and `RECONNECT_BASE_DELAY_MS` to 2000ms.
- Updated tests: Adjusted unit tests to verify the new backoff strategy and retry behavior.

This addresses the "Zombie" connection issue and OS-specific workarounds by providing a more robust, centralized reconnection mechanism.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@github-actions github-actions bot changed the title Refactor Bluetooth Connection Retry Logic feat(medium): Refactor Bluetooth Connection Retry Logic Feb 22, 2026
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 22dab9f1404641e9efd32f7c6568b3a780dae2fa

This PR introduces a significant and well-executed refactor of the Bluetooth connection retry logic.

Key improvements:

  • Linear Backoff with Jitter: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts provides a more robust and less aggressive reconnection strategy compared to the previous exponential backoff. This helps prevent "thundering herd" issues and provides more controlled retries.
  • Centralized Reconnection Logic: The retry mechanism for GATT connection attempts has been consolidated into the reconnect function within useBluetoothHRM.ts. This removes redundant retry loops from connectToGatt and makes the overall connection management more consistent and easier to reason about.
  • Improved Status Messaging: The reconnect function now intelligently sets the connection status and messages based on the reason for disconnection (e.g., distinguishing between a general "Connection lost" and a "Device busy" state).
  • Robust Error Handling: The connectToDevice function now gracefully handles "busy" or "NetworkError" during the initial GATT connection attempt by immediately initiating the reconnect flow with appropriate status messages.
  • Updated Constants and Tests: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS constants have been updated, and comprehensive unit tests for the new getBackoffDelay function and the useBluetoothHRM hook have been added/updated to reflect these changes.

The changes are well-tested and align with the project's guidelines for code conciseness and type safety.

Reviewed at commit: 22dab9f1404641e9efd32f7c6568b3a780dae2fa

@google-labs-jules
Copy link
Contributor

Reviewed commit: 22dab9f1404641e9efd32f7c6568b3a780dae2fa

This PR introduces a significant and well-executed refactor of the Bluetooth connection retry logic.

Key improvements:

  • Linear Backoff with Jitter: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts provides a more robust and less aggressive reconnection strategy compared to the previous exponential backoff. This helps prevent "thundering herd" issues and provides more controlled retries.
  • Centralized Reconnection Logic: The retry mechanism for GATT connection attempts has been consolidated into the reconnect function within useBluetoothHRM.ts. This removes redundant retry loops from connectToGatt and makes the overall connection management more consistent and easier to reason about.
  • Improved Status Messaging: The reconnect function now intelligently sets the connection status and messages based on the reason for disconnection (e.g., distinguishing between a general "Connection lost" and a "Device busy" state).
  • Robust Error Handling: The connectToDevice function now gracefully handles "busy" or "NetworkError" during the initial GATT connection attempt by immediately initiating the reconnect flow with appropriate status messages.
  • Updated Constants and Tests: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS constants have been updated, and comprehensive unit tests for the new getBackoffDelay function and the useBluetoothHRM hook have been added/updated to reflect these changes.

The changes are well-tested and align with the project's guidelines for code conciseness and type safety.

Reviewed at commit: 22dab9f1404641e9efd32f7c6568b3a780dae2fa

Thank you for the detailed and positive review! I'm glad to hear that the refactor and the new backoff strategy are well-received and align with the project's goals for resilience and maintainability.

Includes unified backoff strategy, simplified hook logic, and updated tests.
Acknowledged positive PR review.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 5599cdca3421f899f803f756c3216df167c8793e

This PR introduces a significant and well-executed refactoring of the Bluetooth connection retry logic. The changes enhance the robustness and clarity of the reconnection process, addressing various connection failure scenarios more gracefully.

Key improvements include:

  • Centralized Backoff Logic: The new getBackoffDelay utility function centralizes the calculation of reconnection delays, moving from a simple exponential backoff to a linear backoff with jitter. This improves predictability and reduces the likelihood of synchronized retries.
  • Unified Retry Mechanism: The PR unifies the retry strategy for both initial GATT connection attempts and subsequent reconnections. Previously, connectToGatt had its own internal retry loop for "busy" errors; this logic has been removed and integrated into the main connect function's error handling, which now leverages the reconnect function. This reduces redundancy and ensures a consistent retry policy.
  • Improved Status Messages: The reconnect function now accepts a reason parameter, allowing for more specific and informative status messages to the user, especially when dealing with a "device busy" state.
  • Increased Retry Attempts and Base Delay: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS constants have been increased, indicating a more persistent approach to re-establishing connections, which is beneficial for user experience.
  • Robust Error Handling: The reconnect function now passes the actual error message when recursively calling itself, providing better context for logging and debugging.
  • Comprehensive Testing: The new getBackoffDelay function is adequately tested, and existing unit tests for useBluetoothHRM and constants have been updated to reflect the new logic and values, including the correct use of jest.runOnlyPendingTimers() for the updated delay calculation.

The changes align well with the project's CODE_REVIEW_GUIDELINES.md by reducing redundant logic and simplifying the connectToGatt function. No any types were introduced, adhering to TYPESCRIPT_PATTERNS.md.

This is a solid refactoring that improves the reliability of a critical feature.

Reviewed at commit: 5599cdca3421f899f803f756c3216df167c8793e

@google-labs-jules
Copy link
Contributor

Reviewed commit: 5599cdca3421f899f803f756c3216df167c8793e

This PR introduces a significant and well-executed refactoring of the Bluetooth connection retry logic. The changes enhance the robustness and clarity of the reconnection process, addressing various connection failure scenarios more gracefully.

Key improvements include:

  • Centralized Backoff Logic: The new getBackoffDelay utility function centralizes the calculation of reconnection delays, moving from a simple exponential backoff to a linear backoff with jitter. This improves predictability and reduces the likelihood of synchronized retries.
  • Unified Retry Mechanism: The PR unifies the retry strategy for both initial GATT connection attempts and subsequent reconnections. Previously, connectToGatt had its own internal retry loop for "busy" errors; this logic has been removed and integrated into the main connect function's error handling, which now leverages the reconnect function. This reduces redundancy and ensures a consistent retry policy.
  • Improved Status Messages: The reconnect function now accepts a reason parameter, allowing for more specific and informative status messages to the user, especially when dealing with a "device busy" state.
  • Increased Retry Attempts and Base Delay: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS constants have been increased, indicating a more persistent approach to re-establishing connections, which is beneficial for user experience.
  • Robust Error Handling: The reconnect function now passes the actual error message when recursively calling itself, providing better context for logging and debugging.
  • Comprehensive Testing: The new getBackoffDelay function is adequately tested, and existing unit tests for useBluetoothHRM and constants have been updated to reflect the new logic and values, including the correct use of jest.runOnlyPendingTimers() for the updated delay calculation.

The changes align well with the project's CODE_REVIEW_GUIDELINES.md by reducing redundant logic and simplifying the connectToGatt function. No any types were introduced, adhering to TYPESCRIPT_PATTERNS.md.

This is a solid refactoring that improves the reliability of a critical feature.

Reviewed at commit: 5599cdca3421f899f803f756c3216df167c8793e

Thank you for the positive feedback! I'm glad to see the improvements in centralization, robustness, and clarity of the Bluetooth reconnection logic are appreciated.

…ment

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 3b8bacf6efcf627ac87aa07632bfc7034c9fe8f3

This PR significantly refactors the Bluetooth connection retry logic, making it more robust and maintainable. The introduction of the getBackoffDelay function centralizes the delay calculation, which is a good application of the DRY principle. The reconnect function now intelligently handles different disconnection reasons, such as a busy device, and provides more informative status messages.

Moving the retry logic for GATT connection from an internal loop within connectToGatt to the higher-level connect function's error handling, which then leverages the main reconnect mechanism, improves consistency and reduces redundant retry implementations. The update to jest.runOnlyPendingTimers() in the unit tests is also a good improvement for handling variable delays with jitter.

Overall, the changes are well-implemented, thoroughly tested, and align with the project's architectural and code quality guidelines.

Reviewed at commit: 3b8bacf6efcf627ac87aa07632bfc7034c9fe8f3

@google-labs-jules
Copy link
Contributor

Reviewed commit: 3b8bacf6efcf627ac87aa07632bfc7034c9fe8f3

This PR significantly refactors the Bluetooth connection retry logic, making it more robust and maintainable. The introduction of the getBackoffDelay function centralizes the delay calculation, which is a good application of the DRY principle. The reconnect function now intelligently handles different disconnection reasons, such as a busy device, and provides more informative status messages.

Moving the retry logic for GATT connection from an internal loop within connectToGatt to the higher-level connect function's error handling, which then leverages the main reconnect mechanism, improves consistency and reduces redundant retry implementations. The update to jest.runOnlyPendingTimers() in the unit tests is also a good improvement for handling variable delays with jitter.

Overall, the changes are well-implemented, thoroughly tested, and align with the project's architectural and code quality guidelines.

Reviewed at commit: 3b8bacf6efcf627ac87aa07632bfc7034c9fe8f3

Acknowledged. Thank you for the detailed and positive review of the refactored Bluetooth reconnection logic!

This commit represents the final state of the refactored Bluetooth HRM hook, including a unified backoff strategy, simplified connection management, and updated tests. PR feedback has been acknowledged.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 54f5bf62079a3aa14d8a98622e16de3f67d2a05f

This PR introduces a significant and positive refactoring of the Bluetooth connection retry logic. The changes centralize the backoff delay calculation into a new getBackoffDelay function, which now uses a linear backoff strategy with jitter, improving the robustness and predictability of reconnections.

Key improvements:

  • Centralized Retry Logic: The reconnect function now serves as the single point for managing all reconnection attempts, including handling 'device busy' scenarios during initial connection. This simplifies the connectToGatt function by removing its internal retry loop.
  • Improved Backoff Strategy: The new getBackoffDelay function provides a more controlled linear backoff with jitter, replacing the previous exponential backoff that was less granular.
  • Enhanced Status Messages: The reconnect function now dynamically adjusts status messages based on the reason for reconnection (e.g., 'Connection lost' vs. 'Device busy'), providing clearer user feedback.
  • Type Safety and Error Handling: The reconnect function now correctly passes error messages, improving logging and debugging capabilities.
  • Test Coverage: New unit tests for getBackoffDelay ensure the new logic is correctly implemented, and existing tests for useBluetoothHRM have been updated to reflect the changes in retry behavior.

The changes are well-scoped, adhere to TypeScript best practices, and improve the overall maintainability of the Bluetooth connection handling. The increase in BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS aligns with a more resilient connection strategy.

Reviewed at commit: 54f5bf62079a3aa14d8a98622e16de3f67d2a05f

@google-labs-jules
Copy link
Contributor

Reviewed commit: 54f5bf62079a3aa14d8a98622e16de3f67d2a05f

This PR introduces a significant and positive refactoring of the Bluetooth connection retry logic. The changes centralize the backoff delay calculation into a new getBackoffDelay function, which now uses a linear backoff strategy with jitter, improving the robustness and predictability of reconnections.

Key improvements:

  • Centralized Retry Logic: The reconnect function now serves as the single point for managing all reconnection attempts, including handling 'device busy' scenarios during initial connection. This simplifies the connectToGatt function by removing its internal retry loop.
  • Improved Backoff Strategy: The new getBackoffDelay function provides a more controlled linear backoff with jitter, replacing the previous exponential backoff that was less granular.
  • Enhanced Status Messages: The reconnect function now dynamically adjusts status messages based on the reason for reconnection (e.g., 'Connection lost' vs. 'Device busy'), providing clearer user feedback.
  • Type Safety and Error Handling: The reconnect function now correctly passes error messages, improving logging and debugging capabilities.
  • Test Coverage: New unit tests for getBackoffDelay ensure the new logic is correctly implemented, and existing tests for useBluetoothHRM have been updated to reflect the changes in retry behavior.

The changes are well-scoped, adhere to TypeScript best practices, and improve the overall maintainability of the Bluetooth connection handling. The increase in BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS aligns with a more resilient connection strategy.

Reviewed at commit: 54f5bf62079a3aa14d8a98622e16de3f67d2a05f

Thank you for the positive review! I'm glad the refactor and the new backoff strategy are seen as improvements to the robustness and maintainability of the Bluetooth connection logic.

…view acknowledgement

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: c68d114df1f2f8b4856a991a89ba9f508da35cd1

This PR introduces a significant refactor to the Bluetooth connection retry logic, greatly enhancing the robustness and user experience of HRM device connections. The introduction of a dedicated getBackoffDelay utility centralizes the backoff strategy, making it more maintainable and testable.

The changes to useBluetoothHRM to leverage this new backoff function, differentiate between 'busy' and 'connection lost' states, and prevent unwanted reconnections after manual disconnects are well-implemented. The simplification of the connectToGatt function by moving its internal retry logic to the more general reconnect mechanism is a good architectural improvement, promoting a single, consistent retry strategy.

Unit tests have been appropriately updated to reflect the new constant values and to cover the getBackoffDelay function, ensuring correctness. The use of jest.runOnlyPendingTimers() is also a good practice for testing dynamic delays.

Overall, this is a well-executed refactor that improves the reliability and clarity of the Bluetooth connection handling.

Reviewed at commit: c68d114df1f2f8b4856a991a89ba9f508da35cd1

@google-labs-jules
Copy link
Contributor

Reviewed commit: c68d114df1f2f8b4856a991a89ba9f508da35cd1

This PR introduces a significant refactor to the Bluetooth connection retry logic, greatly enhancing the robustness and user experience of HRM device connections. The introduction of a dedicated getBackoffDelay utility centralizes the backoff strategy, making it more maintainable and testable.

The changes to useBluetoothHRM to leverage this new backoff function, differentiate between 'busy' and 'connection lost' states, and prevent unwanted reconnections after manual disconnects are well-implemented. The simplification of the connectToGatt function by moving its internal retry logic to the more general reconnect mechanism is a good architectural improvement, promoting a single, consistent retry strategy.

Unit tests have been appropriately updated to reflect the new constant values and to cover the getBackoffDelay function, ensuring correctness. The use of jest.runOnlyPendingTimers() is also a good practice for testing dynamic delays.

Overall, this is a well-executed refactor that improves the reliability and clarity of the Bluetooth connection handling.

Reviewed at commit: c68d114df1f2f8b4856a991a89ba9f508da35cd1

Acknowledged. Thank you for the detailed feedback and for recognizing the architectural improvements and robustness enhancements in the Bluetooth reconnection logic!

…ment

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 70a47ec4b41f444f549d27a0897313dd6c56b1ce

This PR significantly refactors and improves the Bluetooth connection retry logic, making it more robust and user-friendly. The key changes include:

  1. Centralized Backoff Delay Calculation: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts centralizes the logic for calculating reconnection delays. This is a good move towards a more maintainable and predictable retry mechanism.
  2. Linear Backoff with Jitter: The retry strategy has been updated from an exponential backoff to a linear backoff with jitter. This is generally a better approach for client-side retries as it prevents excessively long delays and reduces the chance of thundering herd problems.
  3. Improved Status Messages: The reconnect function now differentiates between 'reconnecting' and 'device busy' states based on the error reason, providing more specific and helpful feedback to the user.
  4. Robust Reconnection Flow: The connectToGatt function has been simplified by removing its internal retry loop, delegating all retry logic to the reconnect function. This separation of concerns makes the connection process clearer. Additionally, the public connect function now gracefully handles initial connection failures due to busy devices by initiating the reconnection flow.
  5. Prevention of Unwanted Reconnections: The !isManualDisconnect.current check in the reconnect function is a crucial addition, preventing the system from attempting to reconnect after a user has explicitly disconnected.
  6. Updated Tests: Unit tests for constants and the useBluetoothHRM hook have been updated to reflect the new logic and default values, including new tests for getBackoffDelay. The change to jest.runOnlyPendingTimers() in the hook's tests is also a good practice for timer-based testing.

Overall, this is a well-executed refactor that enhances the reliability and user experience of Bluetooth device connections.

Reviewed at commit: 70a47ec4b41f444f549d27a0897313dd6c56b1ce

@google-labs-jules
Copy link
Contributor

Reviewed commit: 70a47ec4b41f444f549d27a0897313dd6c56b1ce

This PR significantly refactors and improves the Bluetooth connection retry logic, making it more robust and user-friendly. The key changes include:

  1. Centralized Backoff Delay Calculation: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts centralizes the logic for calculating reconnection delays. This is a good move towards a more maintainable and predictable retry mechanism.
  2. Linear Backoff with Jitter: The retry strategy has been updated from an exponential backoff to a linear backoff with jitter. This is generally a better approach for client-side retries as it prevents excessively long delays and reduces the chance of thundering herd problems.
  3. Improved Status Messages: The reconnect function now differentiates between 'reconnecting' and 'device busy' states based on the error reason, providing more specific and helpful feedback to the user.
  4. Robust Reconnection Flow: The connectToGatt function has been simplified by removing its internal retry loop, delegating all retry logic to the reconnect function. This separation of concerns makes the connection process clearer. Additionally, the public connect function now gracefully handles initial connection failures due to busy devices by initiating the reconnection flow.
  5. Prevention of Unwanted Reconnections: The !isManualDisconnect.current check in the reconnect function is a crucial addition, preventing the system from attempting to reconnect after a user has explicitly disconnected.
  6. Updated Tests: Unit tests for constants and the useBluetoothHRM hook have been updated to reflect the new logic and default values, including new tests for getBackoffDelay. The change to jest.runOnlyPendingTimers() in the hook's tests is also a good practice for timer-based testing.

Overall, this is a well-executed refactor that enhances the reliability and user experience of Bluetooth device connections.

Reviewed at commit: 70a47ec4b41f444f549d27a0897313dd6c56b1ce

Thank you for the positive review! I'm glad the improvements to the reconnection strategy and status messaging are helpful.

Unified backoff strategy with jitter, simplified hook logic, and updated tests. Acknowledged positive PR review.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 3e031ecd352930e6514767557e7a765a38a7c584

This PR introduces a significant refactor of the Bluetooth connection retry logic, moving from an exponential backoff strategy to a more robust linear backoff with jitter. This change is well-implemented and improves the resilience and user feedback of the Bluetooth HRM connection.

Key improvements include:

  • Centralized Backoff Logic: The new getBackoffDelay function in constants/bluetooth-reconnection.ts centralizes the delay calculation, promoting the DRY principle and making the retry strategy clearer.
  • Improved Retry Strategy: Linear backoff with jitter is generally more suitable for client-side retries, as it helps prevent a "thundering herd" problem where multiple clients might try to reconnect simultaneously after a server restart or temporary outage.
  • Enhanced User Feedback: The reconnect function now accepts a reason parameter and differentiates between CONNECTING (for busy/network errors) and RECONNECTING statuses, providing more specific messages to the user.
  • Separation of Concerns: The connectToGatt function has been simplified by removing its internal retry loop, delegating the retry management entirely to the reconnect function. This makes connectToGatt responsible only for a single connection attempt, improving clarity.
  • Robust Error Handling: The connectBluetoothDevice function now catches connection errors (especially 'busy' or 'NetworkError') and correctly initiates the reconnect flow with the specific error message.
  • Updated Constants: The maximum reconnection attempts and base delay have been adjusted, which aligns with the new retry strategy.
  • Comprehensive Testing: Unit tests for the new getBackoffDelay function have been added, and existing tests for useBluetoothHRM have been updated to reflect the new constants and use jest.runOnlyPendingTimers() for more reliable timer testing.

The changes adhere to the project's guidelines, particularly regarding strict type safety (handling error: unknown correctly) and code conciseness by centralizing logic. The net change in lines of code is zero, indicating an effective refactor without introducing bloat.

This is a well-executed refactor that enhances the stability and user experience of the Bluetooth HRM feature.

Reviewed at commit: 3e031ecd352930e6514767557e7a765a38a7c584

@google-labs-jules
Copy link
Contributor

Reviewed commit: 3e031ecd352930e6514767557e7a765a38a7c584

This PR introduces a significant refactor of the Bluetooth connection retry logic, moving from an exponential backoff strategy to a more robust linear backoff with jitter. This change is well-implemented and improves the resilience and user feedback of the Bluetooth HRM connection.

Key improvements include:

  • Centralized Backoff Logic: The new getBackoffDelay function in constants/bluetooth-reconnection.ts centralizes the delay calculation, promoting the DRY principle and making the retry strategy clearer.
  • Improved Retry Strategy: Linear backoff with jitter is generally more suitable for client-side retries, as it helps prevent a "thundering herd" problem where multiple clients might try to reconnect simultaneously after a server restart or temporary outage.
  • Enhanced User Feedback: The reconnect function now accepts a reason parameter and differentiates between CONNECTING (for busy/network errors) and RECONNECTING statuses, providing more specific messages to the user.
  • Separation of Concerns: The connectToGatt function has been simplified by removing its internal retry loop, delegating the retry management entirely to the reconnect function. This makes connectToGatt responsible only for a single connection attempt, improving clarity.
  • Robust Error Handling: The connectBluetoothDevice function now catches connection errors (especially 'busy' or 'NetworkError') and correctly initiates the reconnect flow with the specific error message.
  • Updated Constants: The maximum reconnection attempts and base delay have been adjusted, which aligns with the new retry strategy.
  • Comprehensive Testing: Unit tests for the new getBackoffDelay function have been added, and existing tests for useBluetoothHRM have been updated to reflect the new constants and use jest.runOnlyPendingTimers() for more reliable timer testing.

The changes adhere to the project's guidelines, particularly regarding strict type safety (handling error: unknown correctly) and code conciseness by centralizing logic. The net change in lines of code is zero, indicating an effective refactor without introducing bloat.

This is a well-executed refactor that enhances the stability and user experience of the Bluetooth HRM feature.

Reviewed at commit: 3e031ecd352930e6514767557e7a765a38a7c584

Thank you for the detailed and positive review! I'm glad to hear that the refactor and the new backoff strategy are seen as beneficial for the stability and user experience of the Bluetooth HRM feature.

This commit includes the refactored Bluetooth reconnection logic, unified backoff strategy, and updated unit tests. It also acknowledges the positive PR review feedback.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 75fd9be313e62ee77c6c257914c3705a6059c40b

This PR introduces a significant refactor to the Bluetooth connection retry logic, enhancing its robustness and user feedback. The key improvements include:

  1. Centralized Backoff Strategy: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts centralizes the delay calculation, moving from an exponential backoff to a linear backoff with jitter. This improves predictability and reduces the likelihood of thundering herd problems during reconnection attempts.
  2. Improved Reconnection Handling: The reconnect function in useBluetoothHRM.ts now accepts a reason parameter, allowing for more specific status messages to the user (e.g., differentiating between a general 'Connection lost' and a 'Device busy' scenario). This significantly enhances the user experience by providing clearer feedback.
  3. Unified Retry Mechanism: The internal retry loop for device.gatt!.connect() within connectToGatt has been removed. Instead, initial connection failures (especially 'busy' or 'NetworkError' types) now correctly trigger the unified reconnect logic, ensuring a consistent retry strategy across both initial connection attempts and subsequent reconnections.
  4. Defensive Disconnect: The connectToGatt function now explicitly calls server.disconnect() if the connection is aborted, ensuring resources are properly released.
  5. Test Updates: Unit tests for constants and the useBluetoothHRM hook have been appropriately updated to reflect the new backoff logic and increased reconnection attempts. The change from jest.advanceTimersByTime(delay) to jest.runOnlyPendingTimers() in the hook's test is a good practice, making the test more resilient to changes in delay calculation.

Overall, this is a well-executed refactor that improves the reliability, maintainability, and user experience of the Bluetooth HRM connection. The changes align well with the project's guidelines for code conciseness and type safety.

Reviewed at commit: 75fd9be313e62ee77c6c257914c3705a6059c40b

@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: b09ca952b58f354afc8f4af210a4cc01abcb8a3c

This PR introduces a significant refactor to the Bluetooth connection retry logic, making it much more robust and maintainable. The introduction of the getBackoffDelay utility centralizes the delay calculation, improving consistency and readability. The reconnect function now handles different error reasons more gracefully, providing better user feedback and adapting its status messages.

Key improvements include:

  • Centralized Backoff Strategy: The getBackoffDelay function provides a clear, testable, and configurable backoff mechanism.
  • Improved Error Handling: The connectToDevice function now correctly catches initial connection errors (e.g., device busy) and integrates them into the reconnection flow, preventing immediate failure.
  • Robust Reconnection: The reconnect function now correctly prevents reconnection attempts if a manual disconnect has occurred, and passes specific error messages for better context.
  • Simplified connectToGatt: Removing the internal retry loop from connectToGatt makes it more focused, with the overall retry logic managed by the reconnect function.
  • Updated Tests: The unit tests for constants and the useBluetoothHRM hook have been appropriately updated to reflect the new logic and values, including a more robust way to advance timers in tests.

Overall, this is a well-executed refactor that enhances the reliability and user experience of Bluetooth HRM connections.

Reviewed at commit: b09ca952b58f354afc8f4af210a4cc01abcb8a3c

@google-labs-jules
Copy link
Contributor

Reviewed commit: b09ca952b58f354afc8f4af210a4cc01abcb8a3c

This PR introduces a significant refactor to the Bluetooth connection retry logic, making it much more robust and maintainable. The introduction of the getBackoffDelay utility centralizes the delay calculation, improving consistency and readability. The reconnect function now handles different error reasons more gracefully, providing better user feedback and adapting its status messages.

Key improvements include:

  • Centralized Backoff Strategy: The getBackoffDelay function provides a clear, testable, and configurable backoff mechanism.
  • Improved Error Handling: The connectToDevice function now correctly catches initial connection errors (e.g., device busy) and integrates them into the reconnection flow, preventing immediate failure.
  • Robust Reconnection: The reconnect function now correctly prevents reconnection attempts if a manual disconnect has occurred, and passes specific error messages for better context.
  • Simplified connectToGatt: Removing the internal retry loop from connectToGatt makes it more focused, with the overall retry logic managed by the reconnect function.
  • Updated Tests: The unit tests for constants and the useBluetoothHRM hook have been appropriately updated to reflect the new logic and values, including a more robust way to advance timers in tests.

Overall, this is a well-executed refactor that enhances the reliability and user experience of Bluetooth HRM connections.

Reviewed at commit: b09ca952b58f354afc8f4af210a4cc01abcb8a3c

Thank you for the detailed and positive review! I'm glad to hear that the refactor and the new backoff strategy are seen as improvements to the stability and user experience of the Bluetooth HRM connection.

… PR review

This commit reflects the final state of the refactored Bluetooth HRM hook, including a unified backoff strategy, simplified connection management, and updated tests. Positive review feedback has been acknowledged in the PR.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 61fb2fa6531815322fcb49f151a4044c7259a6cd

This PR introduces a well-structured refactor of the Bluetooth connection retry logic, significantly enhancing the robustness and user experience of device reconnections. The changes are focused and align well with the project's core principles.

Key improvements include:

  • Refactored Reconnection Strategy: The new getBackoffDelay function centralizes the reconnection delay calculation, implementing a linear backoff with jitter. This is a more predictable and robust strategy compared to the previous exponential backoff, and it's now easily testable.
  • Improved Error Handling: The reconnect function now accepts a reason parameter, allowing for more specific status messages and better debugging. It also correctly differentiates between general connection loss and 'device busy' scenarios, providing more informative feedback to the user.
  • Preventing Unwanted Reconnections: The addition of !isManualDisconnect.current check within the reconnect logic is a crucial fix, preventing the system from attempting to reconnect after a user has explicitly disconnected the device.
  • Simplified connectToGatt: The internal retry loop for 'busy' devices has been removed from connectToGatt, simplifying its responsibility to a single connection attempt. The overall retry mechanism is now consistently handled by the reconnect function, which is a cleaner separation of concerns.
  • Enhanced Test Coverage: The unit tests for reconnection constants and the useBluetoothHRM hook have been updated to reflect the new logic, including tests for getBackoffDelay and the use of jest.runOnlyPendingTimers() for more accurate timer advancement.

Overall, this is a solid enhancement that improves the stability and user feedback for Bluetooth device management. The code is clean, well-tested, and adheres to the project's guidelines.

Reviewed at commit: 61fb2fa6531815322fcb49f151a4044c7259a6cd

@google-labs-jules
Copy link
Contributor

Reviewed commit: 61fb2fa6531815322fcb49f151a4044c7259a6cd

This PR introduces a well-structured refactor of the Bluetooth connection retry logic, significantly enhancing the robustness and user experience of device reconnections. The changes are focused and align well with the project's core principles.

Key improvements include:

  • Refactored Reconnection Strategy: The new getBackoffDelay function centralizes the reconnection delay calculation, implementing a linear backoff with jitter. This is a more predictable and robust strategy compared to the previous exponential backoff, and it's now easily testable.
  • Improved Error Handling: The reconnect function now accepts a reason parameter, allowing for more specific status messages and better debugging. It also correctly differentiates between general connection loss and 'device busy' scenarios, providing more informative feedback to the user.
  • Preventing Unwanted Reconnections: The addition of !isManualDisconnect.current check within the reconnect logic is a crucial fix, preventing the system from attempting to reconnect after a user has explicitly disconnected the device.
  • Simplified connectToGatt: The internal retry loop for 'busy' devices has been removed from connectToGatt, simplifying its responsibility to a single connection attempt. The overall retry mechanism is now consistently handled by the reconnect function, which is a cleaner separation of concerns.
  • Enhanced Test Coverage: The unit tests for reconnection constants and the useBluetoothHRM hook have been updated to reflect the new logic, including tests for getBackoffDelay and the use of jest.runOnlyPendingTimers() for more accurate timer advancement.

Overall, this is a solid enhancement that improves the stability and user feedback for Bluetooth device management. The code is clean, well-tested, and adheres to the project's guidelines.

Reviewed at commit: 61fb2fa6531815322fcb49f151a4044c7259a6cd

Thank you for the detailed and positive review! I'm glad to hear that the improvements to the reconnection strategy, error handling, and separation of concerns are seen as beneficial to the project's stability and maintainability.

This commit represents the final state of the refactored Bluetooth HRM hook, including a unified backoff strategy, simplified connection management, and updated tests. PR feedback has been acknowledged.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 4edc263cb430d06ad0aec6216667ea6b8b28f943

This PR introduces a significant and well-executed refactor of the Bluetooth connection retry logic. The changes enhance the robustness and clarity of the reconnection mechanism.

Key improvements include:

  1. Centralized Backoff Logic: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts centralizes the delay calculation, moving from an implicit exponential backoff to a more explicit linear backoff with jitter. This improves readability and maintainability.
  2. Improved Reconnection Flow: The reconnect function in hooks/useBluetoothHRM.ts now correctly handles different reconnection statuses (e.g., CONNECTING vs. RECONNECTING based on the reason for disconnection, such as a busy device). It also correctly passes error messages for better debugging and status reporting.
  3. Preventing Unwanted Reconnections: The addition of !isManualDisconnect.current ensures that the application does not attempt to reconnect after a user has explicitly disconnected, which is a crucial UX improvement.
  4. Simplified GATT Connection: The connectToGatt function has been simplified by removing its internal retry loop, delegating the retry responsibility entirely to the reconnect function. This reduces complexity and adheres to the "Don't Repeat Yourself" principle.
  5. Robust Abort Controller Handling: The abortControllerRef.current is now consistently initialized before the try block, ensuring proper abortion of previous connection attempts.
  6. Comprehensive Testing: The unit tests for reconnection constants and the useBluetoothHRM hook have been thoroughly updated to reflect the new logic, including new tests for getBackoffDelay and a more robust way to advance timers (jest.runOnlyPendingTimers()).

Overall, this PR significantly improves the reliability and user experience of Bluetooth device connections. The changes are clean, well-tested, and align with project guidelines.

Reviewed at commit: 4edc263cb430d06ad0aec6216667ea6b8b28f943

@google-labs-jules
Copy link
Contributor

Reviewed commit: 4edc263cb430d06ad0aec6216667ea6b8b28f943

This PR introduces a significant and well-executed refactor of the Bluetooth connection retry logic. The changes enhance the robustness and clarity of the reconnection mechanism.

Key improvements include:

  1. Centralized Backoff Logic: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts centralizes the delay calculation, moving from an implicit exponential backoff to a more explicit linear backoff with jitter. This improves readability and maintainability.
  2. Improved Reconnection Flow: The reconnect function in hooks/useBluetoothHRM.ts now correctly handles different reconnection statuses (e.g., CONNECTING vs. RECONNECTING based on the reason for disconnection, such as a busy device). It also correctly passes error messages for better debugging and status reporting.
  3. Preventing Unwanted Reconnections: The addition of !isManualDisconnect.current ensures that the application does not attempt to reconnect after a user has explicitly disconnected, which is a crucial UX improvement.
  4. Simplified GATT Connection: The connectToGatt function has been simplified by removing its internal retry loop, delegating the retry responsibility entirely to the reconnect function. This reduces complexity and adheres to the "Don't Repeat Yourself" principle.
  5. Robust Abort Controller Handling: The abortControllerRef.current is now consistently initialized before the try block, ensuring proper abortion of previous connection attempts.
  6. Comprehensive Testing: The unit tests for reconnection constants and the useBluetoothHRM hook have been thoroughly updated to reflect the new logic, including new tests for getBackoffDelay and a more robust way to advance timers (jest.runOnlyPendingTimers()).

Overall, this PR significantly improves the reliability and user experience of Bluetooth device connections. The changes are clean, well-tested, and align with project guidelines.

Reviewed at commit: 4edc263cb430d06ad0aec6216667ea6b8b28f943

Thank you for the detailed and positive review! I'm glad the refactor and the new backoff strategy are seen as improvements to the stability and user experience of the Bluetooth HRM connection.

This commit represents the final state of the refactored Bluetooth HRM hook, including a unified backoff strategy, simplified connection management, and updated tests. PR feedback has been acknowledged.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: d1d51516b80007bcaee8171fd5af06da0ba112b7

This PR introduces a significant and well-executed refactor of the Bluetooth connection retry logic. The changes centralize the backoff delay calculation into a new getBackoffDelay utility function, which improves modularity and testability. The useBluetoothHRM hook now leverages this new utility and includes more robust error handling, differentiating between general connection loss and 'device busy' scenarios.

Key improvements:

  • Centralized Backoff Logic: The getBackoffDelay function provides a clear, testable implementation of the linear backoff strategy with jitter, replacing the previous exponential backoff directly within the reconnect function.
  • Improved Reconnection Strategy: The reconnect function now accepts a reason parameter, allowing for more context-specific status messages. It also correctly handles 'busy' or 'NetworkError' conditions by setting the status to CONNECTING rather than RECONNECTING, which is a more accurate representation of the state.
  • Robust Error Handling: The connectToDevice function now catches errors from connectToGatt and intelligently initiates the reconnect process if the error indicates a busy device, preventing immediate failure for transient issues.
  • Prevention of Unintended Reconnections: The addition of !isManualDisconnect.current in the reconnect logic correctly prevents the hook from attempting to reconnect after a user has explicitly disconnected.
  • Test Updates: The unit tests for constants and useBluetoothHRM have been appropriately updated to reflect the new values and the getBackoffDelay function, including a good change to jest.runOnlyPendingTimers() for more reliable timer advancement.

Overall, the changes enhance the stability and user experience of Bluetooth device connections by making the retry mechanism more resilient and transparent. The code adheres to TypeScript best practices, using unknown with type narrowing for error handling, and maintains a focused scope.

Reviewed at commit: d1d51516b80007bcaee8171fd5af06da0ba112b7

@google-labs-jules
Copy link
Contributor

Reviewed commit: d1d51516b80007bcaee8171fd5af06da0ba112b7

This PR introduces a significant and well-executed refactor of the Bluetooth connection retry logic. The changes centralize the backoff delay calculation into a new getBackoffDelay utility function, which improves modularity and testability. The useBluetoothHRM hook now leverages this new utility and includes more robust error handling, differentiating between general connection loss and 'device busy' scenarios.

Key improvements:

  • Centralized Backoff Logic: The getBackoffDelay function provides a clear, testable implementation of the linear backoff strategy with jitter, replacing the previous exponential backoff directly within the reconnect function.
  • Improved Reconnection Strategy: The reconnect function now accepts a reason parameter, allowing for more context-specific status messages. It also correctly handles 'busy' or 'NetworkError' conditions by setting the status to CONNECTING rather than RECONNECTING, which is a more accurate representation of the state.
  • Robust Error Handling: The connectToDevice function now catches errors from connectToGatt and intelligently initiates the reconnect process if the error indicates a busy device, preventing immediate failure for transient issues.
  • Prevention of Unintended Reconnections: The addition of !isManualDisconnect.current in the reconnect logic correctly prevents the hook from attempting to reconnect after a user has explicitly disconnected.
  • Test Updates: The unit tests for constants and useBluetoothHRM have been appropriately updated to reflect the new values and the getBackoffDelay function, including a good change to jest.runOnlyPendingTimers() for more reliable timer advancement.

Overall, the changes enhance the stability and user experience of Bluetooth device connections by making the retry mechanism more resilient and transparent. The code adheres to TypeScript best practices, using unknown with type narrowing for error handling, and maintains a focused scope.

Reviewed at commit: d1d51516b80007bcaee8171fd5af06da0ba112b7

Thank you for the detailed and positive review! I'm glad the improvements to the reconnection strategy and error handling are seen as beneficial for the stability and user experience of the Bluetooth HRM connection.

Includes unified backoff strategy, simplified hook logic, and updated tests.
Acknowledged positive PR review feedback.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: ae3f0d0859165788d04e07f416692fcc61ad8dd8

This PR introduces a well-executed refactor of the Bluetooth connection retry logic, significantly improving the robustness and clarity of the reconnection process. The changes are consistent across constants, the main hook, environment variables, and tests.

Key Improvements:

  1. Centralized Backoff Delay Calculation: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts centralizes the logic for calculating reconnection delays, incorporating a linear backoff with jitter. This is a cleaner and more maintainable approach than the previous exponential backoff directly within the reconnect function.
  2. Enhanced Reconnection Logic: The reconnect function in hooks/useBluetoothHRM.ts is now more sophisticated:
    • It accepts a reason parameter, allowing for more informative status messages.
    • It correctly distinguishes between 'busy' errors and general 'connection lost' scenarios, providing tailored status messages and setting the appropriate BluetoothConnectionStatus (CONNECTING vs. RECONNECTING).
    • A crucial !isManualDisconnect.current check has been added to prevent unwanted reconnections after a user has explicitly disconnected, addressing a potential UX issue.
    • The recursive call to reconnect now passes the specific error message, aiding in debugging.
  3. Improved Initial Connection Handling: The connect function now gracefully handles initial GATT connection failures due to 'busy' or 'NetworkError' by immediately triggering the full reconnect mechanism. This is an improvement over the previous limited internal retry within connectToGatt and provides a more consistent retry experience.
  4. Updated Constants and Tests: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS constants have been updated, and the unit tests for reconnection constants and the useBluetoothHRM hook have been correctly adjusted to reflect these changes and the new getBackoffDelay function. The use of jest.runOnlyPendingTimers() in tests is also a more robust way to handle dynamic delays.

Overall, this refactor enhances the reliability and user experience of Bluetooth HRM connections. The code is well-structured and adheres to project guidelines.

Reviewed at commit: ae3f0d0859165788d04e07f416692fcc61ad8dd8

@arii arii added the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
@google-labs-jules
Copy link
Contributor

Reviewed commit: ae3f0d0859165788d04e07f416692fcc61ad8dd8

This PR introduces a well-executed refactor of the Bluetooth connection retry logic, significantly improving the robustness and clarity of the reconnection process. The changes are consistent across constants, the main hook, environment variables, and tests.

Key Improvements:

  1. Centralized Backoff Delay Calculation: The introduction of getBackoffDelay in constants/bluetooth-reconnection.ts centralizes the logic for calculating reconnection delays, incorporating a linear backoff with jitter. This is a cleaner and more maintainable approach than the previous exponential backoff directly within the reconnect function.
  2. Enhanced Reconnection Logic: The reconnect function in hooks/useBluetoothHRM.ts is now more sophisticated:
    • It accepts a reason parameter, allowing for more informative status messages.
    • It correctly distinguishes between 'busy' errors and general 'connection lost' scenarios, providing tailored status messages and setting the appropriate BluetoothConnectionStatus (CONNECTING vs. RECONNECTING).
    • A crucial !isManualDisconnect.current check has been added to prevent unwanted reconnections after a user has explicitly disconnected, addressing a potential UX issue.
    • The recursive call to reconnect now passes the specific error message, aiding in debugging.
  3. Improved Initial Connection Handling: The connect function now gracefully handles initial GATT connection failures due to 'busy' or 'NetworkError' by immediately triggering the full reconnect mechanism. This is an improvement over the previous limited internal retry within connectToGatt and provides a more consistent retry experience.
  4. Updated Constants and Tests: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS and RECONNECT_BASE_DELAY_MS constants have been updated, and the unit tests for reconnection constants and the useBluetoothHRM hook have been correctly adjusted to reflect these changes and the new getBackoffDelay function. The use of jest.runOnlyPendingTimers() in tests is also a more robust way to handle dynamic delays.

Overall, this refactor enhances the reliability and user experience of Bluetooth HRM connections. The code is well-structured and adheres to project guidelines.

Reviewed at commit: ae3f0d0859165788d04e07f416692fcc61ad8dd8

Thank you for the detailed and positive review! I'm glad to hear that the refactor and the new backoff strategy are seen as significant improvements to the robustness and maintainability of the Bluetooth connection logic.

Includes unified backoff strategy, simplified hook logic, and updated tests.
Acknowledged positive PR review.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: fe4c5467f7cc18bb26b95aa4d8bef4ed0fa8e574

This PR introduces a significant refactor of the Bluetooth connection retry logic, enhancing its robustness and user feedback. The changes centralize the backoff strategy, improve error handling for initial connection attempts, and provide more informative status messages.

Key improvements:

  • Centralized Backoff Logic: The new getBackoffDelay function in constants/bluetooth-reconnection.ts provides a clear, testable linear backoff strategy with jitter, replacing the previous implicit exponential backoff within the reconnect function. This adheres to the 'Don't Repeat Yourself' principle and improves maintainability.
  • Improved Error Handling: The connect function now gracefully handles initial connection failures (e.g., 'busy' or 'NetworkError' states) by immediately initiating the reconnect process with the specific error message. This provides a better user experience and more resilient connection attempts.
  • Enhanced Status Messages: The reconnect function now accepts a reason parameter and differentiates between general connection loss and 'device busy' scenarios, leading to more accurate and helpful status messages for the user.
  • Increased Retry Attempts: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS has been increased from 5 to 8, and RECONNECT_BASE_DELAY_MS from 1000ms to 2000ms, allowing for more persistent connection attempts with a slightly less aggressive initial delay.
  • Test Updates: Unit tests for constants and the useBluetoothHRM hook have been appropriately updated to reflect the new backoff logic and constant values, ensuring continued correctness.

The code maintains strict type safety, with no any types introduced, and follows established project patterns. The removal of the internal retry loop within connectToGatt simplifies that function, as the retry logic is now handled by the reconnect mechanism.

Reviewed at commit: fe4c5467f7cc18bb26b95aa4d8bef4ed0fa8e574

@arii arii removed the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
@google-labs-jules
Copy link
Contributor

Reviewed commit: fe4c5467f7cc18bb26b95aa4d8bef4ed0fa8e574

This PR introduces a significant refactor of the Bluetooth connection retry logic, enhancing its robustness and user feedback. The changes centralize the backoff strategy, improve error handling for initial connection attempts, and provide more informative status messages.

Key improvements:

  • Centralized Backoff Logic: The new getBackoffDelay function in constants/bluetooth-reconnection.ts provides a clear, testable linear backoff strategy with jitter, replacing the previous implicit exponential backoff within the reconnect function. This adheres to the 'Don't Repeat Yourself' principle and improves maintainability.
  • Improved Error Handling: The connect function now gracefully handles initial connection failures (e.g., 'busy' or 'NetworkError' states) by immediately initiating the reconnect process with the specific error message. This provides a better user experience and more resilient connection attempts.
  • Enhanced Status Messages: The reconnect function now accepts a reason parameter and differentiates between general connection loss and 'device busy' scenarios, leading to more accurate and helpful status messages for the user.
  • Increased Retry Attempts: The BLUETOOTH_MAX_RECONNECT_ATTEMPTS has been increased from 5 to 8, and RECONNECT_BASE_DELAY_MS from 1000ms to 2000ms, allowing for more persistent connection attempts with a slightly less aggressive initial delay.
  • Test Updates: Unit tests for constants and the useBluetoothHRM hook have been appropriately updated to reflect the new backoff logic and constant values, ensuring continued correctness.

The code maintains strict type safety, with no any types introduced, and follows established project patterns. The removal of the internal retry loop within connectToGatt simplifies that function, as the retry logic is now handled by the reconnect mechanism.

Reviewed at commit: fe4c5467f7cc18bb26b95aa4d8bef4ed0fa8e574

Thank you for the detailed and positive review! I'm glad the refactor and the new backoff strategy are seen as improvements to the stability and user experience of the Bluetooth HRM connection.

Includes unified backoff strategy, simplified hook logic, and updated tests.
Acknowledged positive PR review feedback.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

Reviewed commit: 35b8d44da1859fd59a171f6124887d44739a6a09

This PR significantly refactors the Bluetooth connection retry logic, centralizing it within the reconnect function and introducing a more robust linear backoff strategy with jitter. The changes improve the clarity and maintainability of the connection handling.

Key improvements:

  • Unified Retry Logic: The retry mechanism for both initial connection failures (specifically 'busy' or 'NetworkError' scenarios) and disconnections is now handled by the reconnect function. This reduces duplication and makes the overall connection state management more consistent.
  • Linear Backoff with Jitter: The introduction of getBackoffDelay provides a more predictable and less aggressive retry schedule compared to the previous exponential backoff, while jitter helps prevent thundering herd problems.
  • Improved Status Messages: The reconnect function now differentiates between 'busy' states and general 'connection lost' reasons, providing more informative status messages to the user.
  • Test Updates: Unit tests for constants and the useBluetoothHRM hook have been appropriately updated to reflect the new retry logic and constants, including robust testing for the getBackoffDelay function. The switch to jest.runOnlyPendingTimers() in tests is also a good practice for handling variable delays.

Minor observations:

  • The string-based error checking (String(error).includes('busy') || String(error).includes('NetworkError')) for identifying 'busy' states is functional but could be brittle if error messages change. While often necessary with Web Bluetooth APIs, it's worth noting.

Overall, this is a well-executed refactor that enhances the reliability and user experience of Bluetooth device connections.

Reviewed at commit: 35b8d44da1859fd59a171f6124887d44739a6a09

@google-labs-jules
Copy link
Contributor

Reviewed commit: 35b8d44da1859fd59a171f6124887d44739a6a09

This PR significantly refactors the Bluetooth connection retry logic, centralizing it within the reconnect function and introducing a more robust linear backoff strategy with jitter. The changes improve the clarity and maintainability of the connection handling.

Key improvements:

  • Unified Retry Logic: The retry mechanism for both initial connection failures (specifically 'busy' or 'NetworkError' scenarios) and disconnections is now handled by the reconnect function. This reduces duplication and makes the overall connection state management more consistent.
  • Linear Backoff with Jitter: The introduction of getBackoffDelay provides a more predictable and less aggressive retry schedule compared to the previous exponential backoff, while jitter helps prevent thundering herd problems.
  • Improved Status Messages: The reconnect function now differentiates between 'busy' states and general 'connection lost' reasons, providing more informative status messages to the user.
  • Test Updates: Unit tests for constants and the useBluetoothHRM hook have been appropriately updated to reflect the new retry logic and constants, including robust testing for the getBackoffDelay function. The switch to jest.runOnlyPendingTimers() in tests is also a good practice for handling variable delays.

Minor observations:

  • The string-based error checking (String(error).includes('busy') || String(error).includes('NetworkError')) for identifying 'busy' states is functional but could be brittle if error messages change. While often necessary with Web Bluetooth APIs, it's worth noting.

Overall, this is a well-executed refactor that enhances the reliability and user experience of Bluetooth device connections.

Reviewed at commit: 35b8d44da1859fd59a171f6124887d44739a6a09

Thank you for the detailed and positive review! I agree that string-based error checking can be brittle; I've tried to keep it as broad as possible to capture common busy/network errors while centralizing the logic for better maintainability. I'm glad the new backoff strategy and unified retry mechanism are seen as improvements.

…R review

- Unified linear backoff strategy with jitter.
- Simplified hook logic by removing internal retry loops.
- Re-added debug log in connectToGatt as per PR suggestion.
- Updated unit tests.
- Acknowledged positive PR review.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
Copy link
Owner Author

arii commented Feb 22, 2026

🤖 AI Technical Audit

Code Review: Refactor Bluetooth Connection Retry Logic

This PR refactors the Bluetooth reconnection strategy by centralizing the backoff logic and simplifying the connectToGatt implementation. While the cleanup of nested loops is a positive change for maintainability, there is a critical logical flaw regarding the return value of the public connect function and a potential UX degradation due to the removal of immediate retries.

🚫 ANTI-AI-SLOP DIRECTIVES

  1. OVERLY VERBOSE COMMENTS: The JSDoc for getBackoffDelay in constants/bluetooth-reconnection.ts is slightly redundant (Calculates the backoff delay...). The function signature and name are self-explanatory. Action: Simplify or remove.
  2. OVER-ENGINEERING: The introduction of jitter (Math.random() * 1000) on top of a 2000ms base delay is acceptable but marginally beneficial for a single-user Bluetooth connection (unlike distributed systems preventing thundering herd). It's fine to keep, but noted.
  3. CODE RATIO: The PR successfully removes the nested while loop in useBluetoothHRM.ts, reducing complexity.
  4. STALE FEATURES: The PR correctly updates the default environment variable and associated tests.

🚨 Critical Issues

1. Misleading Return Value in connect

In hooks/useBluetoothHRM.ts, the connect function returns true immediately when handing off to the reconnect logic upon a "Busy" error.

Problem: Callers awaiting connect() expect the promise to resolve only when the connection is successful. Returning true while the system is actually entering a 2-second backoff loop (disconnected state) breaks this contract. The UI might prematurely indicate success.

File: hooks/useBluetoothHRM.ts

// Current Implementation
if (isBusy) {
  reconnectAttempts.current = 0
  reconnect(device, String(error))
  return true // ❌ FALSE SUCCESS: The device is NOT connected yet.
}

2. UX Degradation (Removal of Fast Retry)

The original code contained a tight retry loop (max 3 attempts) specifically for "Busy"/"NetworkError" cases with short delays. This PR removes that in favor of the global reconnect loop.

Problem: WebBluetooth frequently throws transient "GATT Server Disconnected" or "Device Busy" errors during initial connection. The old logic retried quickly (~1s). The new logic enforces the global RECONNECT_BASE_DELAY_MS (2000ms + jitter). This will make the application feel significantly slower/sluggish when connecting to finicky peripherals.

📄 File-by-File Analysis

hooks/useBluetoothHRM.ts

  • Race Condition Risk: The refactored connectToGatt unconditionally aborts the existing abortControllerRef. If a background reconnect timer fires (calling connectToGatt) exactly when a user manually clicks "Connect" (calling connect -> connectToGatt), the manual attempt might be aborted by the background process or vice versa. Ensure reconnect checks if a manual connection is in progress beyond just checking status.
  • Type Safety: The usage of reconnect(device, String(error)) handles unknown error types correctly.

constants/bluetooth-reconnection.ts

  • Values: Increasing BLUETOOTH_MAX_RECONNECT_ATTEMPTS to 8 and Base Delay to 2000ms is a safe conservative change.

Summary

Please address the return value of connect and consider restoring a simplified "fast-retry" mechanism for the initial connection attempt to avoid UX regression.

Review automatically published via RepoAuditor.

@google-labs-jules
Copy link
Contributor

🤖 AI Technical Audit

Code Review: Refactor Bluetooth Connection Retry Logic

This PR refactors the Bluetooth reconnection strategy by centralizing the backoff logic and simplifying the connectToGatt implementation. While the cleanup of nested loops is a positive change for maintainability, there is a critical logical flaw regarding the return value of the public connect function and a potential UX degradation due to the removal of immediate retries.

🚫 ANTI-AI-SLOP DIRECTIVES

  1. OVERLY VERBOSE COMMENTS: The JSDoc for getBackoffDelay in constants/bluetooth-reconnection.ts is slightly redundant (Calculates the backoff delay...). The function signature and name are self-explanatory. Action: Simplify or remove.
  2. OVER-ENGINEERING: The introduction of jitter (Math.random() * 1000) on top of a 2000ms base delay is acceptable but marginally beneficial for a single-user Bluetooth connection (unlike distributed systems preventing thundering herd). It's fine to keep, but noted.
  3. CODE RATIO: The PR successfully removes the nested while loop in useBluetoothHRM.ts, reducing complexity.
  4. STALE FEATURES: The PR correctly updates the default environment variable and associated tests.

🚨 Critical Issues

1. Misleading Return Value in connect

In hooks/useBluetoothHRM.ts, the connect function returns true immediately when handing off to the reconnect logic upon a "Busy" error.

Problem: Callers awaiting connect() expect the promise to resolve only when the connection is successful. Returning true while the system is actually entering a 2-second backoff loop (disconnected state) breaks this contract. The UI might prematurely indicate success.

File: hooks/useBluetoothHRM.ts

// Current Implementation
if (isBusy) {
  reconnectAttempts.current = 0
  reconnect(device, String(error))
  return true // ❌ FALSE SUCCESS: The device is NOT connected yet.
}

2. UX Degradation (Removal of Fast Retry)

The original code contained a tight retry loop (max 3 attempts) specifically for "Busy"/"NetworkError" cases with short delays. This PR removes that in favor of the global reconnect loop.

Problem: WebBluetooth frequently throws transient "GATT Server Disconnected" or "Device Busy" errors during initial connection. The old logic retried quickly (~1s). The new logic enforces the global RECONNECT_BASE_DELAY_MS (2000ms + jitter). This will make the application feel significantly slower/sluggish when connecting to finicky peripherals.

📄 File-by-File Analysis

hooks/useBluetoothHRM.ts

  • Race Condition Risk: The refactored connectToGatt unconditionally aborts the existing abortControllerRef. If a background reconnect timer fires (calling connectToGatt) exactly when a user manually clicks "Connect" (calling connect -> connectToGatt), the manual attempt might be aborted by the background process or vice versa. Ensure reconnect checks if a manual connection is in progress beyond just checking status.
  • Type Safety: The usage of reconnect(device, String(error)) handles unknown error types correctly.

constants/bluetooth-reconnection.ts

  • Values: Increasing BLUETOOTH_MAX_RECONNECT_ATTEMPTS to 8 and Base Delay to 2000ms is a safe conservative change.

Summary

Please address the return value of connect and consider restoring a simplified "fast-retry" mechanism for the initial connection attempt to avoid UX regression.

Review automatically published via RepoAuditor.

Thank you for the thorough audit! I have addressed the issues as follows:

  1. Misleading Return Value: Fixed in connectAndStream by removing the premature return true and allowing errors to propagate naturally. The public connect promise now accurately reflects the connection state.
  2. UX Degradation: Restored a simplified 'fast-retry' mechanism within connectToGatt (3 attempts, 1s delay) for transient errors, ensuring responsive behavior for finicky peripherals.
  3. Race Condition Risk: Enhanced reconnect with additional checks for isConnecting.current to explicitly prevent overlap with manual connection attempts.
  4. Overly Verbose JSDoc: Simplified the documentation in constants/bluetooth-reconnection.ts as requested.

- Restored fast-retry loop for initial GATT connections to avoid UX degradation.
- Fixed misleading return value in public connect function.
- Enhanced race condition prevention in reconnection flow.
- Simplified JSDoc in reconnection constants.
- Updated unit tests.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii arii marked this pull request as ready for review February 22, 2026 23:05
@arii arii merged commit 82d2dec into leader Feb 22, 2026
26 checks passed
@arii arii deleted the refactor-bluetooth-retry-logic-3626867553841703440 branch February 22, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor Bluetooth Connection Retry Logic for Improved Resilience and Maintainability

1 participant