Don't actually heartbeat with sqlite

Disables internal heartbeat mechanism when ironic has been
configured to utilize a SQLite database backend.

This is done to lessen the possibility of a
"database is locked" error, which can occur when two
distinct threads attempt to write to the database
at the same time with open writers.

The process keepalive heartbeat process was identified as
a major source of these write operations as it was writing
every ten seconds by default, which would also collide with
periodic tasks.

Change-Id: I7b6d7a78ba2910f22673ad8e72e255f321d3fdff
This commit is contained in:
Julia Kreger
2023-07-13 14:35:49 -07:00
parent 54da324900
commit 0099d1812d
10 changed files with 223 additions and 18 deletions

View File

@@ -355,10 +355,14 @@ def _paginate_query(model, limit=None, marker=None, sort_key=None,
def _filter_active_conductors(query, interval=None):
if interval is None:
interval = CONF.conductor.heartbeat_timeout
limit = timeutils.utcnow() - datetime.timedelta(seconds=interval)
query = (query.filter(models.Conductor.online.is_(True))
.filter(models.Conductor.updated_at >= limit))
if not utils.is_ironic_using_sqlite() and interval > 0:
# Check for greater than zero becaues if the value is zero,
# then the logic makes no sense.
limit = timeutils.utcnow() - datetime.timedelta(seconds=interval)
query = (query.filter(models.Conductor.online.is_(True))
.filter(models.Conductor.updated_at >= limit))
else:
query = query.filter(models.Conductor.online.is_(True))
return query
@@ -1433,10 +1437,16 @@ class Connection(api.Connection):
def get_offline_conductors(self, field='hostname'):
with _session_for_read() as session:
field = getattr(models.Conductor, field)
interval = CONF.conductor.heartbeat_timeout
limit = timeutils.utcnow() - datetime.timedelta(seconds=interval)
result = (session.query(field)
.filter(models.Conductor.updated_at < limit))
if not utils.is_ironic_using_sqlite():
interval = CONF.conductor.heartbeat_timeout
limit = (timeutils.utcnow()
- datetime.timedelta(seconds=interval))
result = (session.query(field)
.filter(models.Conductor.updated_at < limit))
else:
result = session.query(
field
).filter(models.Conductor.online.is_(False))
return [row[0] for row in result]
def get_online_conductors(self):