From 9901f3c3dd0346fb7bf2ed3a157d47fec9d2ce2c Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Thu, 9 Jan 2025 10:53:33 +0100 Subject: [PATCH] Add jitter to backup start time to avoid thundering herd (#135065) --- homeassistant/components/backup/config.py | 7 +++++++ tests/components/backup/test_websocket.py | 2 ++ 2 files changed, 9 insertions(+) diff --git a/homeassistant/components/backup/config.py b/homeassistant/components/backup/config.py index 3c5d5d39f7e..7c40792aec5 100644 --- a/homeassistant/components/backup/config.py +++ b/homeassistant/components/backup/config.py @@ -7,6 +7,7 @@ from collections.abc import Callable from dataclasses import dataclass, field, replace from datetime import datetime, timedelta from enum import StrEnum +import random from typing import TYPE_CHECKING, Self, TypedDict from cronsim import CronSim @@ -28,6 +29,10 @@ if TYPE_CHECKING: CRON_PATTERN_DAILY = "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): """Represent the stored backup config.""" @@ -329,6 +334,8 @@ class BackupSchedule: except Exception: # noqa: BLE001 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.hass, _create_backup, next_time ) diff --git a/tests/components/backup/test_websocket.py b/tests/components/backup/test_websocket.py index 307a1d79e0c..e95481373d6 100644 --- a/tests/components/backup/test_websocket.py +++ b/tests/components/backup/test_websocket.py @@ -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( hass: HomeAssistant, 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( hass: HomeAssistant, hass_ws_client: WebSocketGenerator,