Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do DB reconnect indefinitely by default #109

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ configuration.yaml
(string)(Required)
The URL that points to your database.

db_retry_wait
(float)(Optional)
Time to wait between DB reconnects.

db_retry_limit
(int)(Optional)
Max number of times to retry DB reconnect on startup. Defaults to 10. If set to `null` (without quotes) LTSS will try to reconnect to the DB indefinitely. Note that this setting applies only to LTSS startup; during normal operation LTSS will retry 10 times and then drop the write to prevent filling up the internal queue.

chunk_time_interval
(int)(Optional)
The time interval to be used for chunking in TimescaleDB in microseconds. Defaults to 2592000000000 (30 days). Ignored for databases without TimescaleDB extension.
Expand Down
30 changes: 23 additions & 7 deletions custom_components/ltss/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,20 @@

CONF_DB_URL = "db_url"
CONF_CHUNK_TIME_INTERVAL = "chunk_time_interval"

CONNECT_RETRY_WAIT = 3
CONF_DB_RETRY_WAIT = "db_retry_wait"
CONF_DB_RETRY_LIMIT = "db_retry_limit"

CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA.extend(
{
vol.Required(CONF_DB_URL): cv.string,
vol.Optional(
CONF_DB_RETRY_WAIT, default=3.0
): cv.positive_float, # time to wait between db reconnects, default 3.0s
vol.Optional(CONF_DB_RETRY_LIMIT, default=10): vol.Any(
None, cv.positive_int
), # max. number of retries when connecting to the DB, no limit by default
vol.Optional(
CONF_CHUNK_TIME_INTERVAL, default=2592000000000
): cv.positive_int, # 30 days
Expand All @@ -71,12 +77,16 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
conf = config[DOMAIN]

db_url = conf.get(CONF_DB_URL)
db_retry_wait = conf.get(CONF_DB_RETRY_WAIT)
db_retry_limit = conf.get(CONF_DB_RETRY_LIMIT)
chunk_time_interval = conf.get(CONF_CHUNK_TIME_INTERVAL)
entity_filter = convert_include_exclude_filter(conf)

instance = LTSS_DB(
hass=hass,
uri=db_url,
db_retry_wait=db_retry_wait,
db_retry_limit=db_retry_limit,
chunk_time_interval=chunk_time_interval,
entity_filter=entity_filter,
)
Expand All @@ -94,6 +104,8 @@ def __init__(
hass: HomeAssistant,
uri: str,
chunk_time_interval: int,
db_retry_wait: int,
db_retry_limit: int,
entity_filter: Callable[[str], bool],
) -> None:
"""Initialize the ltss."""
Expand All @@ -103,6 +115,8 @@ def __init__(
self.queue: Any = queue.Queue()
self.recording_start = dt_util.utcnow()
self.db_url = uri
self.db_retry_wait = db_retry_wait
self.db_retry_limit = db_retry_limit
self.chunk_time_interval = chunk_time_interval
self.async_db_ready = asyncio.Future()
self.engine: Any = None
Expand All @@ -122,9 +136,11 @@ def run(self):
tries = 1
connected = False

while not connected and tries <= 10:
while not connected and (
self.db_retry_limit is None or tries <= self.db_retry_limit
):
if tries != 1:
time.sleep(CONNECT_RETRY_WAIT)
time.sleep(self.db_retry_wait)
try:
self._setup_connection()
connected = True
Expand All @@ -133,7 +149,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 @@ -201,7 +217,7 @@ def notify_hass_started(event):
updated = False
while not updated and tries <= 10:
if tries != 1:
time.sleep(CONNECT_RETRY_WAIT)
time.sleep(self.db_retry_wait)
try:
with self.get_session() as session:
with session.begin():
Expand All @@ -221,7 +237,7 @@ def notify_hass_started(event):
"Error in database connectivity: %s. "
"(retrying in %s seconds)",
err,
CONNECT_RETRY_WAIT,
self.db_retry_wait,
)
tries += 1

Expand Down
2 changes: 2 additions & 0 deletions tests/pytest/test_databases.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ def ltss_init_wrapper(container):
"postgresql://postgres@localhost:"
+ container.ports["5432/tcp"][0]["HostPort"],
123,
3.0,
10,
lambda x: False,
)

Expand Down