Failed _write now track that the DB is inconsistent

Consistency is restored on next transaction
This commit is contained in:
Peter Josef Scheibel 2022-02-04 13:50:29 -05:00 committed by Peter Scheibel
parent cf1349ba35
commit e63b4f752a

View file

@ -358,6 +358,14 @@ def __init__(self, root, db_dir=None, upstream_dbs=None,
self.is_upstream = is_upstream self.is_upstream = is_upstream
self.last_seen_verifier = '' self.last_seen_verifier = ''
# Failed write transactions (interrupted by exceptions) will alert
# _write. When that happens, we set this flag to indicate that
# future read/write transactions should re-read the DB. Normally it
# would make more sense to resolve this at the end of the transaction
# but typically a failed transaction will terminate the running
# instance of Spack and we don't want to incur an extra read in that
# case, so we defer the cleanup to when we begin the next transaction
self._state_is_inconsistent = False
# initialize rest of state. # initialize rest of state.
self.db_lock_timeout = ( self.db_lock_timeout = (
@ -992,6 +1000,10 @@ def _write(self, type, value, traceback):
""" """
# Do not write if exceptions were raised # Do not write if exceptions were raised
if type is not None: if type is not None:
# A failure interrupted a transaction, so we should record that
# the Database is now in an inconsistent state: we should
# restore it in the next transaction
self._state_is_inconsistent = True
return return
temp_file = self._index_path + ( temp_file = self._index_path + (
@ -1030,6 +1042,9 @@ def _read(self):
self.last_seen_verifier = current_verifier self.last_seen_verifier = current_verifier
# Read from file if a database exists # Read from file if a database exists
self._read_from_file(self._index_path) self._read_from_file(self._index_path)
elif self._state_is_inconsistent:
self._read_from_file(self._index_path)
self._state_is_inconsistent = False
return return
elif self.is_upstream: elif self.is_upstream:
raise UpstreamDatabaseLockingError( raise UpstreamDatabaseLockingError(