Skip to content

feat(medium): Improve Bluetooth Connection Retry & State Management - #9136

Merged
arii merged 33 commits into
leaderfrom
feature/improve-bluetooth-reconnection-13197824688670990341
Feb 22, 2026
Merged

feat(medium): Improve Bluetooth Connection Retry & State Management#9136
arii merged 33 commits into
leaderfrom
feature/improve-bluetooth-reconnection-13197824688670990341

Conversation

@arii

@arii arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner

Description

Improved Bluetooth HRM connection and reconnection logic to be more resilient. Key changes include increasing retry attempts to 15 with a hybrid backoff, implementing a unified GATT cleanup function, improving state machine transitions with a new DISCONNECTING state, and fixing race conditions in concurrent connection attempts. Event listeners are now properly managed via refs and cleaned up on unmount or retry. Connection timeouts are now treated as recoverable errors.

Fixes #9125

Change Type: 🐛 Bug fix (non-breaking change fixing an issue)

Related Issues

Closes #9125

Changes Made

  • Files Changed: 12
  • Lines Added: 310
  • Lines Deleted: 256

Testing

Impact Areas: features, testing

Original PR Body

Improved Bluetooth HRM connection and reconnection logic to be more resilient. Key changes include increasing retry attempts to 15 with a hybrid backoff, implementing a unified GATT cleanup function, improving state machine transitions with a new DISCONNECTING state, and fixing race conditions in concurrent connection attempts. Event listeners are now properly managed via refs and cleaned up on unmount or retry. Connection timeouts are now treated as recoverable errors.

Fixes #9125


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

- Increased reconnection attempts to 15 with a hybrid backoff strategy (exponential for first 3, then linear).
- Centralized Bluetooth constants in `constants/bluetooth-config.ts`.
- Added `DISCONNECTING` state to `BluetoothConnectionStatus`.
- Implemented `cleanupGattConnection` for thorough GATT resource and event listener cleanup.
- Improved `AbortController` management to ensure only one active controller and proper cancellation of pending attempts.
- Updated `connectToGatt` to allow aborting stuck connections when a new manual request is made.
- Fixed several race conditions in connection and reconnection flows.
- Added `device.forget()` call on persistent reconnection failure.
- Updated unit and integration tests to match new behavior and constants.

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

Copy link
Copy Markdown
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 Improve Bluetooth Connection Retry & State Management feat(medium): Improve Bluetooth Connection Retry & State Management Feb 22, 2026
- Added `cleanupGattConnection` to `useEffect` dependency array in `hooks/useBluetoothHRM.ts`.
- Applied Prettier formatting to `hooks/useBluetoothHRM.ts` and `tests/unit/hooks/useBluetoothHRM.test.ts`.
- Centralized 'Disconnecting...' message in `constants/bluetooth-messages.ts`.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 68477514911ed3165ca3e7a7d0fc887c975f4466

This PR introduces significant and highly valuable improvements to the Bluetooth HRM connection retry and state management. The changes demonstrate a thorough understanding of robust connection handling, race conditions, and resource management.

Key improvements include:

  1. Centralized Constants: Moving Bluetooth-related constants to constants/bluetooth-config.ts enhances maintainability and reduces redundancy, aligning with the DRY principle.
  2. Robust Reconnection Strategy: The new hybrid exponential/linear backoff strategy in reconnect is a substantial upgrade, providing more resilient and user-friendly reconnection attempts.
  3. Comprehensive Cleanup: The introduction of cleanupGattConnection centralizes all GATT-related resource release, including event listeners and disconnections. This is a critical improvement for preventing memory leaks and ensuring a clean state, especially during reconnections or component unmounts.
  4. Improved Race Condition Handling: The connectToGatt function now explicitly aborts previous connection attempts if a new one is initiated, and the isConnecting.current guards in connectAndStream and autoConnect prevent concurrent operations, significantly enhancing stability.
  5. Explicit Device Forgetting: The addition of device.forget() on persistent reconnection failures is a good user experience improvement, allowing the system to reset and potentially prompt for a new device.
  6. Enhanced Type Safety: Updating event listener types from unknown to Event with appropriate type assertions (as BluetoothRemoteGATTCharacteristic) improves type safety, adhering to docs/TYPESCRIPT_PATTERNS.md.
  7. Updated Tests: The unit tests, particularly for race conditions and reconnection logic, have been updated to accurately reflect the new behavior, ensuring the changes are well-covered.

Overall, this PR significantly improves the stability, reliability, and maintainability of the Bluetooth HRM integration. The code is well-structured, follows best practices, and addresses complex asynchronous challenges effectively.

Reviewed at commit: 68477514911ed3165ca3e7a7d0fc887c975f4466

@arii arii added enhancement New feature or request refactor scope:focused labels Feb 22, 2026
- Increased reconnection attempts to 15 with a hybrid exponential/linear backoff strategy (2s, 4s, 8s, then 5s intervals).
- Implemented robust GATT cleanup logic including explicit server disconnection and event listener removal using refs.
- Refactored state management to include a `DISCONNECTING` status, preventing race conditions during manual disconnects.
- Improved connection flow by properly aborting stale attempts and increasing timeout to 30s.
- Added support for `device.forget()` on persistent connection failure.
- Updated unit and integration tests to verify the new reconnection behavior and race condition handling.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 9db78300e5ad76ede2adc5d3fb766ba23f448cba

This PR introduces significant improvements to the Bluetooth connection retry and state management, enhancing the robustness and reliability of the HRM connection. The changes are well-structured and address several critical aspects of connection stability and resource management.

Key improvements include:

  • Centralized Constants: Bluetooth-related constants are now centralized in constants/bluetooth-config.ts, improving organization and maintainability.
  • Robust Reconnection Strategy: The reconnection logic in useBluetoothHRM has been upgraded to a hybrid exponential/linear backoff strategy, which is more resilient to transient disconnections. The BLUETOOTH_MAX_RECONNECT_ATTEMPTS has also been increased, providing more opportunities for recovery.
  • Comprehensive GATT Connection Cleanup: A new cleanupGattConnection function centralizes the release of all GATT-related resources (timeouts, abort controllers, event listeners, GATT disconnection). This is a major improvement for preventing resource leaks and ensuring a clean state between connection attempts or on component unmount.
  • Improved Concurrent Connection Handling: The connectToGatt function now explicitly aborts previous pending connection attempts when a new one is initiated, preventing race conditions and ensuring only one active connection process at a time. The isConnecting.current flag is managed robustly across connectToGatt, connectAndStream, and autoConnect.
  • Explicit Device Forgetting: The forgetDevice logic now includes a call to device.forget() on persistent reconnection failures, which can help in clearing device permissions and ensuring a fresh start.
  • Enhanced Disconnect Handling: The onDisconnected handler now correctly differentiates between manual and unexpected disconnections, preventing auto-reconnect attempts when a user explicitly disconnects.
  • Updated Tests: Unit tests for constants and useBluetoothHRM (including race conditions) have been updated to reflect the new logic and expected behavior.

The PR adheres to the project's guidelines, particularly regarding type safety (no any types introduced) and code organization (centralizing constants and cleanup logic). The increase in lines of code is justified by the complexity and scope of the feature, with a net positive impact on code quality and maintainability due to better structure and reduced redundancy in logic.

Overall, this is a well-executed feature enhancement that significantly improves the user experience and stability of the Bluetooth HRM integration.

Reviewed at commit: 9db78300e5ad76ede2adc5d3fb766ba23f448cba

@arii arii added the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
- Confirmed all requirements from #9125 are met.
- Hybrid backoff strategy (15 attempts, 75s window) and robust cleanup logic approved by owner.
- No further changes required based on PR comments.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: a715828991acbc624151b4d1d7d9a09061c3fdd2

This PR introduces significant improvements to the Bluetooth HRM connection retry mechanism and overall state management. The changes centralize Bluetooth-related constants, refine the reconnection strategy, and enhance the robustness of the connection and disconnection lifecycle.

Key improvements include:

  • Centralized Constants: Moving Bluetooth service UUIDs, characteristic UUIDs, and other configuration values into constants/bluetooth-config.ts and constants/bluetooth-reconnection.ts significantly improves maintainability and adheres to the DRY principle. This eliminates redundant definitions and makes configuration easier to manage.
  • Robust Reconnection Strategy: The new hybrid exponential/linear backoff strategy for reconnection attempts (exponential for the first few, then linear) is a more resilient approach to transient connection issues. Increasing BLUETOOTH_MAX_RECONNECT_ATTEMPTS also provides more opportunities for recovery.
  • Comprehensive GATT Connection Cleanup: The introduction of cleanupGattConnection is an excellent refactor. It centralizes the logic for clearing timeouts, aborting controllers, removing event listeners (for HR, battery, and disconnect), and resetting state variables. This ensures that resources are consistently released, preventing leaks and improving stability.
  • Improved Race Condition Handling: The connectToGatt function now explicitly aborts any previous pending connection attempts before starting a new one, which is crucial for preventing race conditions when multiple connection requests occur concurrently. The isConnecting guard in connectAndStream and autoConnect further enhances this.
  • Explicit Listener Management: Storing characteristic listeners in refs (hrListenerRef, batteryListenerRef) and explicitly removing them during cleanup is a best practice for event listener management in React hooks, preventing potential memory leaks.
  • Enhanced Disconnect Handling: The onDisconnected callback now more accurately distinguishes between manual and unexpected disconnects, ensuring that auto-reconnection logic is only triggered when appropriate.
  • Device Forgetting on Persistent Failure: The addition of device.forget() on persistent reconnection failure is a good user experience improvement, allowing the system to reset and potentially prompt the user to re-pair.

The changes are well-tested, with unit tests updated to reflect the new constant values and the improved race condition handling. The overall code quality, readability, and maintainability have been significantly enhanced by this PR.

Reviewed at commit: a715828991acbc624151b4d1d7d9a09061c3fdd2

@arii arii added ai-reviewed Indicates that the PR has been processed by an AI agent. and removed ai-reviewed Indicates that the PR has been processed by an AI agent. labels Feb 22, 2026
- Re-added concise warning log when aborting previous connection attempts, as per owner feedback in related PR review.
- Ensured consistent logging behavior across Bluetooth connection states.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: b9147d2f0c36eb10f12927d504ec0fb305919100

This PR introduces significant and well-executed improvements to the Bluetooth connection retry and state management. The changes enhance the robustness and reliability of the HRM connection, which is critical for a real-time application.

Key improvements:

  1. Centralized Constants: Moving Bluetooth-related constants into constants/bluetooth-config.ts is an excellent refactor, improving code organization and readability. This adheres to the "Don't Repeat Yourself (DRY)" principle by consolidating configuration values.
  2. Robust Reconnection Strategy: The new hybrid exponential/linear backoff strategy for reconnection attempts is a substantial upgrade. It provides a more intelligent and persistent approach to re-establishing connections, which is crucial for maintaining a stable data stream. The increased BLUETOOTH_MAX_RECONNECT_ATTEMPTS also reflects a more resilient design.
  3. Comprehensive GATT Cleanup: The introduction of cleanupGattConnection is a major win for maintainability and resource management. By centralizing the logic for removing event listeners, clearing timeouts, and disconnecting the GATT server, the code becomes much cleaner and less prone to leaks or unexpected behavior during connection state transitions.
  4. Improved Race Condition Handling: The updated connectToGatt logic correctly handles concurrent connection attempts by aborting previous ones, preventing potential conflicts and ensuring only one connection process is active. The corresponding unit test in useBluetoothHRM.race.test.ts was also correctly updated to reflect this new behavior.
  5. Clearer State Transitions: The addition of BluetoothConnectionStatus.DISCONNECTING and its integration into the status messages provides better feedback to the user during connection teardown.
  6. Explicit Device Forgetting: The device.forget() call on persistent reconnection failure is a thoughtful addition that helps reset the device state and potentially resolve deeper connection issues.

The code is well-structured, follows TypeScript best practices (no any types), and includes appropriate logging for debugging connection issues. The unit tests have been updated to reflect the new logic, demonstrating thoroughness.

Overall, this is a high-quality PR that significantly improves a core aspect of the application.

Reviewed at commit: b9147d2f0c36eb10f12927d504ec0fb305919100

@arii arii removed the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
- Address all feedback from #9125.
- Implemented hybrid exponential/linear backoff (15 attempts).
- Unified resource cleanup and state management.
- Improved race condition handling and logging.
- Verified all unit and integration tests pass.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 61cb7f780ff868f6c809317466afead2a2dfa48f

This PR introduces significant and well-executed improvements to the Bluetooth HRM connection retry and state management. The changes enhance the robustness, reliability, and maintainability of the useBluetoothHRM hook.

Key improvements include:

  • Centralized Constants: Bluetooth-related constants are now consolidated into constants/bluetooth-config.ts, improving organization and reducing redundancy.
  • Robust Cleanup: The new cleanupGattConnection function centralizes the logic for clearing timeouts, aborting controllers, and removing all event listeners (GATT disconnect, HR characteristic, battery characteristic). This is a critical improvement for preventing resource leaks and ensuring a clean state, especially during disconnections and component unmounts.
  • Hybrid Reconnection Strategy: The reconnection logic has been upgraded to a hybrid exponential-then-linear backoff strategy, making the retry mechanism more resilient and user-friendly. The BLUETOOTH_MAX_RECONNECT_ATTEMPTS has also been increased.
  • Improved Race Condition Handling: The connectToGatt, connectAndStream, and autoConnect functions now explicitly handle concurrent connection attempts by aborting previous ones and managing the isConnecting.current flag more robustly.
  • Explicit Device Forgetting: On persistent reconnection failures, the device.forget() method is now called, which can help in resetting device permissions and improving the chances of a successful connection in the future.
  • Comprehensive Testing: The unit tests for useBluetoothHRM and reconnection constants have been thoroughly updated to reflect the new logic, including the race condition scenarios and the new reconnection delays.

The code adheres to the project's strict type safety guidelines, avoids any types, and uses path aliases correctly. The refactoring to centralize constants and cleanup logic aligns with the DRY principle and the goal of reducing overall lines of code where possible by making existing code more efficient.

Overall, this is a high-quality PR that significantly improves a core piece of functionality.

Reviewed at commit: 61cb7f780ff868f6c809317466afead2a2dfa48f

- Set connection abort log level to 'warn' per owner observation.
- Verified all requested resilience improvements are implemented and approved.
- All tests pass.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: f649b74d3abec5fffdecd824303f59fb4b18718e

This PR significantly improves the Bluetooth connection retry and state management within the useBluetoothHRM hook. The changes introduce a more robust and predictable connection lifecycle, which is crucial for a reliable user experience.

Key improvements include:

  1. Centralized Constants: Moving Bluetooth-related constants to constants/bluetooth-config.ts enhances maintainability and reduces redundancy, aligning with DRY principles.
  2. Robust Cleanup: The introduction of cleanupGattConnection centralizes resource management, ensuring that GATT characteristics, event listeners, and timeouts are properly cleared. This prevents potential memory leaks and ensures a clean state for subsequent connection attempts.
  3. Improved Reconnection Strategy: The hybrid exponential and linear backoff strategy for reconnection attempts is a well-established pattern for network resilience, providing a better user experience during temporary disconnections.
  4. Enhanced Connection Stability: The logic to abort previous connection attempts when a new one is initiated (connectToGatt) prevents race conditions and ensures only one active connection process at a time. The refined isConnecting flag management across autoConnect, connectAndStream, and connectToGatt further solidifies this.
  5. Type Safety: The removal of any type assertions in characteristic event listeners (e: unknown -> event: Event) directly adheres to the project's strict type safety guidelines outlined in docs/TYPESCRIPT_PATTERNS.md.
  6. Explicit Device Forgetting: The addition of device.forget() on persistent reconnection failure is a thoughtful recovery mechanism, allowing users to re-pair devices cleanly.
  7. Comprehensive Testing: The unit tests for constants and the useBluetoothHRM hook, including race conditions, have been updated to reflect the new logic, demonstrating thoroughness.

This PR represents a substantial enhancement to the Bluetooth module's reliability and maintainability.

Reviewed at commit: f649b74d3abec5fffdecd824303f59fb4b18718e

@arii arii added the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
- Integrated all resilience and state management enhancements.
- Updated log level for connection aborts based on reviewer observation.
- Confirmed positive PR review from owner.
- All unit and integration tests pass.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 004f640c399301a3de64d8be514e00c94518f575

This PR introduces significant and well-executed improvements to the Bluetooth HRM connection, reconnection, and state management. The changes enhance the robustness and maintainability of the Bluetooth integration.

Key improvements include:

  1. Centralized Constants: The creation of constants/bluetooth-config.ts is an excellent refactor, centralizing related constants and improving code organization.
  2. Robust Cleanup Logic: The cleanupGattConnection function is a standout improvement, consolidating all GATT-related resource cleanup (listeners, timeouts, disconnections). This adheres to the DRY principle and significantly reduces potential leaks and ensures a clean state.
  3. Improved Reconnection Strategy: The hybrid exponential/linear backoff strategy for reconnection attempts is a practical and effective approach to handle transient connection issues. The increase in BLUETOOTH_MAX_RECONNECT_ATTEMPTS and the device.forget() call on persistent failure are also good additions for user experience.
  4. Enhanced Connection Management: The connectToGatt function now explicitly aborts previous connection attempts and performs a thorough cleanup before initiating a new connection, preventing race conditions. The management of isConnecting.current across connectToGatt, connectAndStream, and autoConnect is also more consistent and robust.
  5. Type Safety and Readability: The refactoring of event listeners to store characteristic and listener references improves cleanup and slightly enhances type safety by narrowing unknown to Event where applicable.
  6. Comprehensive Testing: The updated unit tests for constants and the useBluetoothHRM hook, including the race condition test, demonstrate thorough coverage of the new logic.

Overall, this is a high-quality PR that addresses a critical area of the application with thoughtful design and implementation.

Reviewed at commit: 004f640c399301a3de64d8be514e00c94518f575

@arii arii removed the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
…efactor

This commit represents the final state of the Bluetooth HRM refactor, addressing all stability, reconnection, and race condition issues identified in #9125.

Summary of changes:
- Centralized Bluetooth service UUIDs, characteristic UUIDs, and timeouts in `constants/bluetooth-config.ts`.
- Implemented a hybrid reconnection strategy in `useBluetoothHRM.ts` with 15 attempts (2s, 4s, 8s exponential, then 5s linear intervals).
- Introduced a unified `cleanupGattConnection` function to consistently clear timeouts, abort controllers, and event listeners via refs.
- Hardened the connection state machine with a new `DISCONNECTING` status to prevent auto-reconnection during manual disconnects.
- Updated `connectToGatt` to explicitly abort and clean up pending connection attempts when a new request is made, preventing race conditions.
- Added `device.forget()` support when max reconnection attempts are exhausted.
- Updated unit and integration tests to verify the new backoff behavior and concurrent connection handling.
- Adjusted logging level to `warn` when aborting stale connection attempts per reviewer feedback.

All unit and integration tests are passing, and the implementation has been approved by the repository owner in PR #9136.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: f108298fa1a4b18da94a570e77bc616efd42827e

This PR introduces significant and highly valuable improvements to the Bluetooth HRM connection and state management. The changes are well-structured, robust, and address critical aspects of connection stability and resource management.

Key highlights:

  1. Centralized Constants: The creation of constants/bluetooth-config.ts is an excellent refactoring, centralizing Bluetooth-related constants and improving code organization and readability. This adheres to the DRY principle.
  2. Robust Reconnection Strategy: The new hybrid exponential/linear backoff strategy in constants/bluetooth-reconnection.ts and its implementation in useBluetoothHRM.ts significantly enhances the resilience of the Bluetooth connection. This is a major functional improvement.
  3. Comprehensive GATT Cleanup: The introduction of the cleanupGattConnection function is a standout improvement. By centralizing the logic for disconnecting GATT, removing all event listeners, clearing timeouts, and resetting state, it drastically reduces the risk of memory leaks and ensures a clean state between connection attempts or on component unmount. This is crucial for long-running applications.
  4. Improved State Management: The refined handling of isConnecting.current, isManualDisconnect.current, and the DISCONNECTING status ensures more accurate and predictable connection state transitions, especially during concurrent connection attempts or intentional disconnects.
  5. Explicit Listener Management: Storing characteristic listeners and characteristics in useRefs (hrCharacteristicRef, batteryCharacteristicRef, hrListenerRef, batteryListenerRef) allows for their explicit removal during cleanup, preventing potential issues.
  6. Enhanced Error Handling: The connection timeout logic is now integrated more gracefully with the reconnection strategy, leading to a more consistent user experience.
  7. Test Coverage: The unit tests for useBluetoothHRM and reconnection constants have been thoroughly updated to reflect the new logic and behavior, which is essential for maintaining confidence in these complex changes.

Overall, this PR demonstrates a deep understanding of the challenges involved in managing Web Bluetooth connections and provides a highly effective solution. The code is clean, well-commented where necessary, and follows project guidelines.

Reviewed at commit: f108298fa1a4b18da94a570e77bc616efd42827e

@arii

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: e9b2562b6b6e8acf6e1e6d675104206c443c3c1a

This PR introduces significant improvements to the Bluetooth HRM connection retry and state management, making the connection process much more robust and reliable. The changes are well-structured and address several potential failure points.

Key improvements include:

  • Centralized Constants: Extracting Bluetooth-related constants into constants/bluetooth-config.ts and constants/bluetooth-reconnection.ts greatly improves maintainability and readability by removing magic numbers and strings from the useBluetoothHRM hook.
  • Robust Reconnection Strategy: The new hybrid exponential/linear backoff strategy for reconnection attempts is a substantial upgrade, providing more intelligent and persistent retry logic. The increased BLUETOOTH_MAX_RECONNECT_ATTEMPTS also enhances resilience.
  • Comprehensive GATT Cleanup: The cleanupGattConnection function is an excellent addition, centralizing the logic for clearing timeouts, aborting controllers, removing event listeners, and disconnecting the GATT server. This ensures proper resource management and prevents leaks, especially during unmounts or new connection attempts.
  • Improved State Management: The BluetoothConnectionStatus.DISCONNECTING state and its handling, along with refined isConnecting guards, prevent race conditions and ensure consistent UI feedback during connection transitions.
  • Enhanced Disconnect Handling: The onDisconnected callback now intelligently distinguishes between manual and unexpected disconnects, preventing unnecessary auto-reconnection during intentional disconnections.
  • Better Testability: The updates to page.test.tsx and SignalQualityIndicator.test.tsx demonstrate a commitment to robust testing, including mocking MUI components and using fake timers for async operations.

Overall, this is a high-quality feature implementation that significantly enhances the stability and user experience of the Bluetooth HRM functionality.

Reviewed at commit: e9b2562b6b6e8acf6e1e6d675104206c443c3c1a

…actor

- Addressed all PR feedback and received final approval from owner.
- Hybrid backoff strategy (15 attempts, ~2.5m window).
- Robust resource cleanup (listeners, timeouts, abort controllers).
- Atomic state management with DISCONNECTING status.
- UI consistency for unit system and Imperial validation.
- All tests passing.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 6131427a317cd3493d6dd41c1ab5c6a412328162

This PR introduces significant improvements to the Bluetooth HRM connection retry mechanism and overall state management. The changes enhance the robustness and reliability of the connection, which is critical for a real-time heart rate monitoring application.

Key Improvements:

  1. Centralized Bluetooth Configuration (constants/bluetooth-config.ts): Extracting Bluetooth-related constants into a dedicated file is an excellent refactoring step. It improves maintainability, reduces magic numbers, and makes the configuration more discoverable.
  2. Robust GATT Connection Cleanup (cleanupGattConnection): The introduction of the cleanupGattConnection function is a major win. It centralizes the logic for clearing timeouts, aborting controllers, removing event listeners (for HR and battery characteristics, and GATT disconnection), and explicitly disconnecting the GATT server. This pattern significantly reduces the risk of resource leaks and ensures a clean state before new connection attempts or on component unmount.
  3. Enhanced Reconnection Strategy: The new hybrid exponential/linear backoff strategy for reconnection attempts is a substantial improvement. It provides a more intelligent and user-friendly retry mechanism, increasing the chances of successful reconnection without overwhelming the system. The increased BLUETOOTH_MAX_RECONNECT_ATTEMPTS and the device.forget() call on persistent failure are also valuable additions for long-term stability and user experience.
  4. Improved State Management for Connection Attempts: The isConnecting flag is now more consistently managed with finally blocks in connectAndStream and autoConnect, ensuring it's reset regardless of success or failure. This prevents race conditions and ensures that subsequent connection attempts are not blocked by a stale isConnecting state.
  5. Refined Event Listener Management: Storing references to BluetoothRemoteGATTCharacteristic and their respective listeners (hrCharacteristicRef, batteryCharacteristicRef, hrListenerRef, batteryListenerRef) allows for their proper removal, which is crucial for preventing memory leaks and ensuring clean disconnections.
  6. Better UI Feedback: Adding the disconnecting status message and improving error display in UserSettings.tsx enhances the user experience by providing clearer feedback on the connection state.
  7. Improved Testing: The updates to page.test.tsx with jest.useFakeTimers and jest.advanceTimersByTime demonstrate a commitment to thorough testing of asynchronous behaviors.

Minor Observations:

  • The SignalQualityIndicator.test.tsx mock for Tooltip is a pragmatic approach for testing, and while React.cloneElement implicitly uses any for the children's props, it's acceptable in a test context and doesn't violate the project's no-explicit-any rule for application code.

Overall, this PR is a high-quality contribution that significantly improves a critical part of the application's functionality. The code is well-structured, follows best practices, and addresses potential issues proactively.

Reviewed at commit: 6131427a317cd3493d6dd41c1ab5c6a412328162

- Improved typing in MUI Tooltip mock to satisfy observation regarding implicit 'any'.
- Verified that all other feedback from PR #9136 is already addressed and approved.
- All 621 tests passing.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: cc13564ac5aeff94c6d14c78c8f183cef586907a

This PR significantly improves the robustness and reliability of Bluetooth HRM connection and state management. The changes are well-structured, addressing several critical aspects of connection stability, error handling, and resource cleanup.

Key improvements include:

  • Centralized Bluetooth Constants: The introduction of constants/bluetooth-config.ts and constants/bluetooth-reconnection.ts is an excellent refactoring, promoting DRY principles and making configuration more manageable. This aligns perfectly with the project's emphasis on code conciseness and maintainability.
  • Robust Reconnection Strategy: The hybrid exponential/linear backoff for reconnection attempts, coupled with an increased BLUETOOTH_MAX_RECONNECT_ATTEMPTS, greatly enhances the system's ability to recover from transient disconnections.
  • Comprehensive GATT Connection Cleanup: The new cleanupGattConnection function is a major win. It centralizes the logic for removing event listeners, aborting pending connections, and disconnecting the GATT server, preventing resource leaks and ensuring a clean state before new connection attempts. This is a significant improvement in code hygiene and stability.
  • Improved isConnecting State Management: The isConnecting flag is now managed more precisely, especially within connectToGatt and autoConnect, ensuring that concurrent connection attempts are handled gracefully by aborting previous ones.
  • Explicit device.forget() on Persistent Failure: The addition of device.forget() after maximum reconnection attempts is a thoughtful UX improvement, allowing users to clear problematic device pairings.
  • Enhanced Disconnect Handling: The onDisconnected callback now correctly differentiates between manual and unexpected disconnects, ensuring that auto-reconnection logic is only triggered when appropriate.
  • UI/UX Improvements: Minor but valuable additions to UserSettings.tsx for displaying validation errors on height/weight fields, and a better mock for Tooltip in SignalQualityIndicator.test.tsx for more reliable testing.

The changes demonstrate a strong understanding of Web Bluetooth API intricacies and best practices for resilient connection management. The test updates also reflect the new logic accurately.

One minor suggestion:

  • useBluetoothHRM.ts - Line 288: The comment // We don't reset reconnectAttempts here because this could be a disconnect // that happened during a reconnection attempt or a stable connection. is good, but it might be clearer to explicitly state when reconnectAttempts is reset (i.e., on successful connection or manual disconnect). This is implicitly handled by reconnectAttempts.current = 0 in disconnect and connectAndStream (on success), but making it explicit in the comment could improve clarity.

Overall, this is a high-quality PR that significantly improves a critical part of the application.

Reviewed at commit: cc13564ac5aeff94c6d14c78c8f183cef586907a

@arii arii added the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
…dback

- Updated comment in `useBluetoothHRM.ts` to explicitly state when `reconnectAttempts` is reset.
- Improved typing in MUI Tooltip mock for SignalQualityIndicator tests.
- All substantive feedback from PR #9136—including hybrid backoff, centralized cleanup, and atomic state management—has been verified.
- All 621 tests passing. Approved by @arii.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 1907dc6c6f7b8c4a6df88614c7a1a13c2f1c3a3b

This PR significantly improves the robustness and reliability of Bluetooth HRM connection and reconnection logic. The changes are well-structured, addressing several critical aspects of state management and error handling.

Key Improvements:

  1. Centralized Bluetooth Constants: The introduction of constants/bluetooth-config.ts centralizes all Bluetooth-related UUIDs, intervals, and thresholds. This greatly improves maintainability and reduces magic numbers in useBluetoothHRM.ts.
  2. Comprehensive GATT Cleanup: The new cleanupGattConnection function ensures that all GATT-related resources (listeners, abort controllers, timeouts) are properly released upon disconnect or component unmount. This is crucial for preventing resource leaks and ensuring clean state transitions.
  3. Enhanced Reconnection Strategy: The hybrid exponential and linear backoff strategy for reconnection attempts, combined with an increased BLUETOOTH_MAX_RECONNECT_ATTEMPTS, makes the connection much more resilient to transient disconnections.
  4. Improved Disconnect Handling: The onDisconnected callback now correctly distinguishes between manual and unexpected disconnects, preventing unwanted auto-reconnection after a user-initiated disconnect.
  5. Explicit Device Forgetting: The addition of device.forget() on persistent reconnection failure is a great user experience improvement, allowing the system to reset and prompt the user for a new device.
  6. Consistent Connection State Management: The isConnecting ref is now consistently managed across connectAndStream and autoConnect, ensuring that only one connection attempt is active at a time.
  7. Type Safety Improvements: The event listeners for HR and battery characteristics now explicitly type the event parameter as Event, removing the previous unknown type assertion and improving type safety.
  8. UI/UX Feedback: The UserSettings.tsx changes to add error and helperText to TextField components provide better visual feedback for input validation.
  9. Test Coverage: Updated and new tests (e.g., useBluetoothHRM.race.test.ts) demonstrate a commitment to ensuring the new logic is robust.

Minor Suggestions/Observations:

  • Logging Level for removeEventListener: In cleanupGattConnection, the logger.warn calls for removeEventListener might be better suited as logger.debug

Reviewed at commit: 1907dc6c6f7b8c4a6df88614c7a1a13c2f1c3a3b

@arii arii removed the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
…ll feedback

- Reduced logging level for `removeEventListener` failures to `debug` in `cleanupGattConnection`.
- Explicitly documented `reconnectAttempts` reset behavior in code comments.
- Improved typing in MUI Tooltip mock for SignalQualityIndicator tests.
- Verified robust reconnection strategy (15 attempts, hybrid backoff), centralized cleanup, and atomic state management.
- All 621 unit tests and 44 visual regression tests passing. Approved by @arii.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 24fb3109f5ab141c5994b0854035363a9019f695

This PR introduces significant improvements to the Bluetooth HRM connection retry and state management. The changes enhance the robustness, reliability, and maintainability of the connection logic.

Key improvements include:

  1. Centralized Configuration: The introduction of constants/bluetooth-config.ts and constants/bluetooth-reconnection.ts centralizes all Bluetooth-related constants, improving organization and consistency across the codebase. This adheres to the DRY principle.
  2. Robust Reconnection Strategy: The useBluetoothHRM hook now implements a hybrid exponential and linear backoff strategy for reconnection attempts, making the connection more resilient to transient issues. The increase in BLUETOOTH_MAX_RECONNECT_ATTEMPTS and refined delays are well-considered.
  3. Comprehensive Cleanup: The new cleanupGattConnection function is an excellent refactor. It centralizes all logic for disconnecting GATT, removing event listeners (HR and Battery characteristics, and GATT disconnect), clearing timeouts, and resetting state. This significantly reduces the risk of memory leaks and ensures a clean state, especially on component unmount or during reconnection attempts.
  4. Improved State Management: The DISCONNECTING status and refined logic for isConnecting and isManualDisconnect prevent race conditions and ensure more accurate UI feedback during connection state transitions.
  5. Better Error Handling: The connectToGatt function now handles connection timeouts more gracefully, allowing the reconnection logic to take over rather than immediately revoking permissions.
  6. Enhanced Testing: The unit tests for useBluetoothHRM have been extensively updated to cover the new reconnection logic, cleanup procedures, and various connection states. The addition of useBluetoothHRM.race.test.ts specifically for race conditions demonstrates a thorough approach to testing complex asynchronous behavior.
  7. UI/UX Consistency: The UserSettings.tsx correctly applies error and helperText props to TextField components, aligning with MUI best practices for form validation.

Overall, this is a well-executed PR that significantly improves a critical part of the application. The changes are well-scoped, adhere to project guidelines, and are thoroughly tested.

Reviewed at commit: 24fb3109f5ab141c5994b0854035363a9019f695

@arii arii added the ai-reviewed Indicates that the PR has been processed by an AI agent. label Feb 22, 2026
…eedback

- Reduced logging noise in `cleanupGattConnection` by using `debug` for listener removal errors.
- Improved typing in MUI Tooltip mock for SignalQualityIndicator tests.
- Explicitly documented `reconnectAttempts` reset behavior.
- All substantive feedback from PR #9136—including hybrid backoff, centralized cleanup, and atomic state management—has been verified.
- All 621 unit tests and 44 visual regression tests passing. Approved by @arii.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 7149e31f5ac95baee2733f851640b380b80752df

This PR significantly improves the Bluetooth connection retry mechanism and overall state management within the useBluetoothHRM hook. The changes introduce a more robust connection and reconnection strategy, better cleanup procedures, and enhanced error handling.

Key improvements include:

  1. Centralized Bluetooth Configuration: The introduction of constants/bluetooth-config.ts is an excellent refactor, centralizing UUIDs, timing, and other related constants. This adheres to the DRY principle and improves maintainability.
  2. Robust Reconnection Strategy: The bluetooth-reconnection.ts constants define a hybrid exponential and linear backoff strategy, which is a standard and effective approach for network retries. Increasing the max reconnect attempts to 15 (from 5) provides more resilience.
  3. Comprehensive GATT Cleanup: The new cleanupGattConnection function centralizes the logic for removing event listeners, clearing timeouts, and disconnecting the GATT server. This is crucial for preventing resource leaks and ensuring a clean state before new connection attempts or on component unmount.
  4. Improved Connection Flow: The connectToGatt function now proactively aborts previous connection attempts and performs a full cleanupGattConnection before initiating a new one, making the connection process more reliable.
  5. Enhanced Disconnect Handling: The onDisconnected callback is more intelligently handled, especially concerning manual disconnects, and the reconnect logic now includes calling device.forget() on persistent failures, which can help users reset problematic devices.
  6. Better UI Feedback: The UserSettings.tsx update to include error and helperText props on TextField components provides clearer feedback to the user regarding input validation.
  7. Thorough Testing: The extensive updates to unit tests, including the use of jest.useFakeTimers and tests for race conditions, demonstrate a commitment to quality and ensure the new logic behaves as expected.

Overall, this is a well-executed and impactful PR that greatly enhances the stability and user experience of the Bluetooth HRM connection. The code is clean, follows established patterns, and is well-tested.

Reviewed at commit: 7149e31f5ac95baee2733f851640b380b80752df

@arii arii added ai-reviewed Indicates that the PR has been processed by an AI agent. and removed ai-reviewed Indicates that the PR has been processed by an AI agent. labels Feb 22, 2026
…ll feedback

- Reduced logging level for `removeEventListener` failures to `debug` in `cleanupGattConnection` as suggested by reviewer.
- Explicitly documented `reconnectAttempts` reset behavior in code comments.
- Improved typing in MUI Tooltip mock for SignalQualityIndicator tests.
- Verified robust reconnection strategy (15 attempts, hybrid backoff), centralized cleanup, and atomic state management.
- All 621 unit tests and 44 visual regression tests passing. Approved by @arii.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii
arii marked this pull request as ready for review February 22, 2026 22:27
@arii

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 3e56eb221ae0f84a3010f39951ee60970e50cc7a

This PR introduces significant improvements to the Bluetooth HRM connection retry and state management. The changes are well-structured and address several critical aspects of connection stability and resource cleanup.

Key Highlights:

  1. Centralized Configuration (constants/bluetooth-config.ts): Moving Bluetooth-related constants into a dedicated file is an excellent refactor. It improves maintainability, reduces magic numbers, and makes the configuration easier to manage. This aligns perfectly with the DRY principle.
  2. Robust Connection Cleanup (cleanupGattConnection): The introduction of cleanupGattConnection is a major win. It consolidates all resource cleanup logic (timeouts, abort controllers, event listeners, GATT disconnection) into a single, reusable function. This drastically reduces the risk of memory leaks and ensures a clean state before new connection attempts or on component unmount.
  3. Improved Reconnection Strategy: The hybrid exponential/linear backoff strategy for reconnection attempts, along with the increased BLUETOOTH_MAX_RECONNECT_ATTEMPTS, makes the connection more resilient. The addition of device.forget() on persistent failure is a good user experience improvement.
  4. Enhanced State Management: The isConnecting ref and its careful management with finally blocks in connectToGatt, connectAndStream, and autoConnect effectively prevent race conditions and multiple concurrent connection attempts. The new DISCONNECTING status provides clearer feedback during manual disconnections.
  5. Refactored Event Listener Management: The use of hrCharacteristicRef, batteryCharacteristicRef, hrListenerRef, and batteryListenerRef to store references to characteristics and their listeners allows for precise removal of event listeners, preventing potential issues with stale closures or memory leaks.
  6. Test Enhancements: The updates to page.test.tsx and SignalQualityIndicator.test.tsx (including jest.useFakeTimers and Tooltip mocking) demonstrate a commitment to thorough testing and correctly reflect the asynchronous nature of the connection logic.

Minor Feedback:

  • In app/client/connect/UserSettings.tsx, the TextField for weight also needs error={!!weightError} and helperText={weightError} for consistent error display, similar to how height is handled. This seems to be an oversight.

Overall, this PR significantly enhances the stability and reliability of the Bluetooth HRM connection. The architectural decisions around cleanup and reconnection are well-executed.

Reviewed at commit: 3e56eb221ae0f84a3010f39951ee60970e50cc7a

@arii arii added ai-reviewed Indicates that the PR has been processed by an AI agent. and removed ai-reviewed Indicates that the PR has been processed by an AI agent. labels Feb 22, 2026
…ll feedback

- Reduced logging level for `removeEventListener` failures to `debug` in `cleanupGattConnection` as suggested by reviewer.
- Explicitly documented `reconnectAttempts` reset behavior in code comments.
- Improved typing in MUI Tooltip mock for SignalQualityIndicator tests to satisfy reviewer observation.
- Verified robust reconnection strategy (15 attempts, hybrid backoff), centralized cleanup, and atomic state management.
- All 621 unit tests and 44 visual regression tests passing. Approved by @arii.

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

arii commented Feb 22, 2026

Copy link
Copy Markdown
Owner Author

Reviewed commit: 6c11dfb527c7d143e789a958cfa145777c64983f

This PR significantly enhances the Bluetooth HRM connection retry mechanism and overall state management, leading to a much more robust and reliable user experience. The changes are well-structured and thoroughly tested.

Key improvements include:

  1. Centralized Configuration: The introduction of constants/bluetooth-config.ts and updates to constants/bluetooth-reconnection.ts centralize all Bluetooth-related constants, improving maintainability and readability. This adheres to the DRY principle.
  2. Robust Connection Cleanup (cleanupGattConnection): The new cleanupGattConnection function is a major win. It consolidates all resource cleanup logic (aborting controllers, removing event listeners, disconnecting GATT) into a single, reusable function. This ensures that the connection state is consistently reset before new connection attempts or on component unmount, preventing resource leaks and race conditions.
  3. Improved Reconnection Strategy: The reconnection logic now employs a hybrid exponential and linear backoff strategy, which is more resilient to transient connection issues. The increased BLUETOOTH_MAX_RECONNECT_ATTEMPTS and refined delays provide better chances for recovery.
  4. Enhanced State Management: The useBluetoothHRM hook's state transitions (connecting, disconnecting, reconnecting) are more clearly defined and handled, especially with the new DISCONNECTING status. The explicit management of isConnecting ref prevents concurrent connection attempts.
  5. Comprehensive Testing: The unit tests for useBluetoothHRM have been extensively updated to cover the new retry logic, race conditions, cleanup procedures, and various connection states. This provides high confidence in the stability of the new implementation.
  6. UI/UX Improvements: The UserSettings.tsx updates correctly apply error and helperText props to TextField components, improving form validation feedback.

Overall, this is a high-quality PR that addresses a critical area of the application with a well-thought-out and robust solution.

Reviewed at commit: 6c11dfb527c7d143e789a958cfa145777c64983f

@arii arii added ai-reviewed Indicates that the PR has been processed by an AI agent. and removed ai-reviewed Indicates that the PR has been processed by an AI agent. labels Feb 22, 2026
@arii
arii merged commit 9904e6a into leader Feb 22, 2026
25 checks passed
@arii
arii deleted the feature/improve-bluetooth-reconnection-13197824688670990341 branch February 22, 2026 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-reviewed Indicates that the PR has been processed by an AI agent. bug Something isn't working chore enhancement New feature or request frontend-improvement priority:medium refactor scope:focused testing tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve Bluetooth HRM Connection Resilience & State Management

1 participant