Skip to content
32 changes: 24 additions & 8 deletions homeassistant/components/recorder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,16 @@

DEFAULT_URL = "sqlite:///{hass_config_path}"
DEFAULT_DB_FILE = "home-assistant_v2.db"
DEFAULT_DB_MAX_RETRIES = 10
DEFAULT_DB_RETRY_WAIT = 3

CONF_DB_URL = "db_url"
CONF_DB_MAX_RETRIES = "db_max_retries"
CONF_DB_RETRY_WAIT = "db_retry_wait"
CONF_PURGE_KEEP_DAYS = "purge_keep_days"
CONF_PURGE_INTERVAL = "purge_interval"
CONF_EVENT_TYPES = "event_types"

CONNECT_RETRY_WAIT = 3

FILTER_SCHEMA = vol.Schema(
{
vol.Optional(CONF_EXCLUDE, default={}): vol.Schema(
Expand Down Expand Up @@ -96,6 +98,12 @@
vol.Coerce(int), vol.Range(min=0)
),
vol.Optional(CONF_DB_URL): cv.string,
vol.Optional(
CONF_DB_MAX_RETRIES, default=DEFAULT_DB_MAX_RETRIES
): cv.positive_int,
vol.Optional(
CONF_DB_RETRY_WAIT, default=DEFAULT_DB_RETRY_WAIT
): cv.positive_int,
}
)
},
Expand Down Expand Up @@ -133,6 +141,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
conf = config[DOMAIN]
keep_days = conf.get(CONF_PURGE_KEEP_DAYS)
purge_interval = conf.get(CONF_PURGE_INTERVAL)
db_max_retries = conf[CONF_DB_MAX_RETRIES]
db_retry_wait = conf[CONF_DB_RETRY_WAIT]

db_url = conf.get(CONF_DB_URL, None)
if not db_url:
Expand All @@ -145,6 +155,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
keep_days=keep_days,
purge_interval=purge_interval,
uri=db_url,
db_max_retries=db_max_retries,
db_retry_wait=db_retry_wait,
include=include,
exclude=exclude,
)
Expand Down Expand Up @@ -174,6 +186,8 @@ def __init__(
keep_days: int,
purge_interval: int,
uri: str,
db_max_retries: int,
db_retry_wait: int,
include: Dict,
exclude: Dict,
) -> None:
Expand All @@ -186,6 +200,8 @@ def __init__(
self.queue: Any = queue.Queue()
self.recording_start = dt_util.utcnow()
self.db_url = uri
self.db_max_retries = db_max_retries
self.db_retry_wait = db_retry_wait
self.async_db_ready = asyncio.Future()
self.engine: Any = None
self.run_info: Any = None
Expand Down Expand Up @@ -217,9 +233,9 @@ def run(self):
tries = 1
connected = False

while not connected and tries <= 10:
while not connected and tries <= self.db_max_retries:
if tries != 1:
time.sleep(CONNECT_RETRY_WAIT)
time.sleep(self.db_retry_wait)
try:
self._setup_connection()
migration.migrate_schema(self)
Expand All @@ -230,7 +246,7 @@ def run(self):
_LOGGER.error(
"Error during connection setup: %s (retrying in %s seconds)",
err,
CONNECT_RETRY_WAIT,
self.db_retry_wait,
)
tries += 1

Expand Down Expand Up @@ -337,9 +353,9 @@ def async_purge(now):

tries = 1
updated = False
while not updated and tries <= 10:
while not updated and tries <= self.db_max_retries:
if tries != 1:
time.sleep(CONNECT_RETRY_WAIT)
time.sleep(self.db_retry_wait)
try:
with session_scope(session=self.get_session()) as session:
try:
Expand Down Expand Up @@ -367,7 +383,7 @@ def async_purge(now):
"Error in database connectivity: %s. "
"(retrying in %s seconds)",
err,
CONNECT_RETRY_WAIT,
self.db_retry_wait,
)
tries += 1

Expand Down
9 changes: 8 additions & 1 deletion tests/components/recorder/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,14 @@ def test_recorder_setup_failure():
):
setup.side_effect = ImportError("driver not found")
rec = Recorder(
hass, keep_days=7, purge_interval=2, uri="sqlite://", include={}, exclude={}
hass,
keep_days=7,
purge_interval=2,
uri="sqlite://",
db_max_retries=10,
db_retry_wait=3,
include={},
exclude={},
)
rec.start()
rec.join()
Expand Down