Skip to content

Commit 86542b8

Browse files
authored
Increase ConfigEntryNotReady retry backoff cap from 80s to 10 minutes (home-assistant#172487)
1 parent 7e07e70 commit 86542b8

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

homeassistant/config_entries.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@
138138

139139
DISCOVERY_COOLDOWN = 1
140140

141+
SETUP_RETRY_MAX_WAIT = 600 # 10 minutes
142+
141143
ISSUE_UNIQUE_ID_COLLISION = "config_entry_unique_id_collision"
142144
UNIQUE_ID_COLLISION_TITLE_LIMIT = 5
143145

@@ -836,7 +838,7 @@ async def __async_setup_with_context(
836838
error_reason_translation_key,
837839
error_reason_translation_placeholders,
838840
)
839-
wait_time = 2 ** min(self._tries, 4) * 5 + (
841+
wait_time = min(2**self._tries * 5, SETUP_RETRY_MAX_WAIT) + (
840842
randint(RANDOM_MICROSECOND_MIN, RANDOM_MICROSECOND_MAX) / 1000000
841843
)
842844
self._tries += 1

tests/test_config_entries.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,44 @@ async def test_setup_raise_not_ready(
17021702
assert entry.reason is None
17031703

17041704

1705+
async def test_setup_not_ready_exponential_backoff(
1706+
hass: HomeAssistant,
1707+
manager: config_entries.ConfigEntries,
1708+
freezer: FrozenDateTimeFactory,
1709+
) -> None:
1710+
"""Test setup retry uses exponential backoff capped at 10 minutes."""
1711+
entry = MockConfigEntry(domain="test")
1712+
entry.add_to_hass(hass)
1713+
1714+
attempts = 0
1715+
1716+
async def _mock_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
1717+
nonlocal attempts
1718+
attempts += 1
1719+
raise ConfigEntryNotReady
1720+
1721+
mock_integration(hass, MockModule("test", async_setup_entry=_mock_setup_entry))
1722+
mock_platform(hass, "test.config_flow", None)
1723+
1724+
await manager.async_setup(entry.entry_id)
1725+
assert attempts == 1
1726+
1727+
expected_waits = [5, 10, 20, 40, 80, 160, 320, 600, 600]
1728+
for i, wait in enumerate(expected_waits):
1729+
# Advance to just before the retry should fire
1730+
freezer.tick(wait - 1)
1731+
async_fire_time_changed(hass)
1732+
await hass.async_block_till_done()
1733+
assert attempts == i + 1, f"Retry {i + 1} fired too early"
1734+
1735+
# Advance past the retry point (+ 1s for jitter)
1736+
freezer.tick(2)
1737+
async_fire_time_changed(hass)
1738+
await hass.async_block_till_done()
1739+
assert attempts == i + 2, f"Retry {i + 1} did not fire"
1740+
assert entry.state is config_entries.ConfigEntryState.SETUP_RETRY
1741+
1742+
17051743
async def test_setup_raise_not_ready_from_exception(
17061744
hass: HomeAssistant,
17071745
manager: config_entries.ConfigEntries,

0 commit comments

Comments
 (0)