Add jitter to backup start time to avoid thundering herd (#135065)

This commit is contained in:
Erik Montnemery 2025-01-09 10:53:33 +01:00 committed by GitHub
parent c9d8c59b45
commit 9901f3c3dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 0 deletions

View File

@ -7,6 +7,7 @@ from collections.abc import Callable
from dataclasses import dataclass, field, replace from dataclasses import dataclass, field, replace
from datetime import datetime, timedelta from datetime import datetime, timedelta
from enum import StrEnum from enum import StrEnum
import random
from typing import TYPE_CHECKING, Self, TypedDict from typing import TYPE_CHECKING, Self, TypedDict
from cronsim import CronSim from cronsim import CronSim
@ -28,6 +29,10 @@ if TYPE_CHECKING:
CRON_PATTERN_DAILY = "45 4 * * *" CRON_PATTERN_DAILY = "45 4 * * *"
CRON_PATTERN_WEEKLY = "45 4 * * {}" CRON_PATTERN_WEEKLY = "45 4 * * {}"
# Randomize the start time of the backup by up to 60 minutes to avoid
# all backups running at the same time.
BACKUP_START_TIME_JITTER = 60 * 60
class StoredBackupConfig(TypedDict): class StoredBackupConfig(TypedDict):
"""Represent the stored backup config.""" """Represent the stored backup config."""
@ -329,6 +334,8 @@ class BackupSchedule:
except Exception: # noqa: BLE001 except Exception: # noqa: BLE001
LOGGER.exception("Unexpected error creating automatic backup") LOGGER.exception("Unexpected error creating automatic backup")
next_time += timedelta(seconds=random.randint(0, BACKUP_START_TIME_JITTER))
LOGGER.debug("Scheduling next automatic backup at %s", next_time)
manager.remove_next_backup_event = async_track_point_in_time( manager.remove_next_backup_event = async_track_point_in_time(
manager.hass, _create_backup, next_time manager.hass, _create_backup, next_time
) )

View File

@ -1345,6 +1345,7 @@ async def test_config_update_errors(
), ),
], ],
) )
@patch("homeassistant.components.backup.config.BACKUP_START_TIME_JITTER", 0)
async def test_config_schedule_logic( async def test_config_schedule_logic(
hass: HomeAssistant, hass: HomeAssistant,
hass_ws_client: WebSocketGenerator, hass_ws_client: WebSocketGenerator,
@ -1787,6 +1788,7 @@ async def test_config_schedule_logic(
), ),
], ],
) )
@patch("homeassistant.components.backup.config.BACKUP_START_TIME_JITTER", 0)
async def test_config_retention_copies_logic( async def test_config_retention_copies_logic(
hass: HomeAssistant, hass: HomeAssistant,
hass_ws_client: WebSocketGenerator, hass_ws_client: WebSocketGenerator,