Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 22, 2025

Summary

The reconnection logic had a critical bug where failed reconnection attempts would not schedule subsequent retries, causing local push to permanently fail until app restart. Additionally, rapid status updates could schedule duplicate timers with incorrect backoff timing.

Root cause: scheduleReconnection() was only called when a server was first added to disconnectedServers. After the first reconnection attempt failed, subsequent status checks found the server already tracked and did nothing, breaking the reconnection chain.

Changes:

  • Renamed scheduleReconnection()scheduleReconnectionIfNeeded() with idempotency guards
  • Always call scheduleReconnectionIfNeeded() for unavailable states (not just initial disconnection)
  • Guard against duplicate timers: skip scheduling if timer already active
  • Clear timer reference when fired to enable next attempt scheduling

Flow before fix:

case .unavailable:
    if !disconnectedServers.contains(server.identifier) {
        disconnectedServers.insert(server.identifier)
        scheduleReconnection()  // Only called once
    } else {
        // Subsequent checks do nothing - reconnection stops!
    }

Flow after fix:

case .unavailable:
    if !disconnectedServers.contains(server.identifier) {
        disconnectedServers.insert(server.identifier)
    }
    // Always attempt scheduling - idempotent guards prevent duplicates
    scheduleReconnectionIfNeeded()

Screenshots

N/A - Internal networking logic change

Link to pull request in Documentation repository

Documentation: home-assistant/companion.home-assistant#

Any other notes

This PR merges into #4113 and addresses feedback from review comment #4113 (comment).


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits December 22, 2025 11:33
…ous reconnection

The reconnection logic had a critical bug where if a reconnection attempt failed,
no further reconnection attempts would be scheduled. This was because the code only
scheduled a reconnection when a server was first added to the disconnectedServers set,
not when subsequent status checks found it still unavailable.

Additionally, multiple rapid status checks could potentially schedule multiple timers
without proper coordination.

Changes:
- Renamed scheduleReconnection() to scheduleReconnectionIfNeeded() to better reflect its idempotent behavior
- Made scheduleReconnectionIfNeeded() idempotent by checking if a timer is already active before scheduling
- Moved scheduleReconnectionIfNeeded() call outside the if/else block so it's called for ALL unavailable states
- Clear the timer reference in attemptReconnection() after the timer fires
- Updated comments to clarify the behavior

This ensures:
1. Only one timer is active at a time (prevents rapid successive attempts)
2. Failed reconnection attempts properly schedule the next attempt with backoff
3. Proper backoff timing is maintained (timer won't be reset prematurely)

Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com>
Added more detailed comments to explain:
- Why scheduleReconnectionIfNeeded() is called for all unavailable states
- The idempotent nature of the scheduling method
- Why the timer is cleared before incrementing the attempt counter

Co-authored-by: bgoncal <5808343+bgoncal@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix local push reliability and reconnection improvements Fix local push reconnection logic to prevent stalled reconnections Dec 22, 2025
Copilot AI requested a review from bgoncal December 22, 2025 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants