Skip to content

Commit

Permalink
recovery for tree cycle errors, #2831
Browse files Browse the repository at this point in the history
  • Loading branch information
zadam committed May 2, 2022
1 parent a9dc625 commit 5dab189
Showing 1 changed file with 41 additions and 16 deletions.
57 changes: 41 additions & 16 deletions src/services/consistency_checks.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,41 +56,66 @@ class ConsistencyChecks {
childToParents[childNoteId].push(parentNoteId);
}

/** @returns {boolean} true if cycle was found and we should try again */
const checkTreeCycle = (noteId, path) => {
if (noteId === 'root') {
return;
}

if (!childToParents[noteId] || childToParents[noteId].length === 0) {
logError(`No parents found for note ${noteId}`);

this.unrecoveredConsistencyErrors = true;
return;
return false;
}

for (const parentNoteId of childToParents[noteId]) {
if (path.includes(parentNoteId)) {
logError(`Tree cycle detected at parent-child relationship: ${parentNoteId} - ${noteId}, whole path: ${path}`);
if (this.autoFix) {
const branch = becca.getBranchFromChildAndParent(noteId, parentNoteId);
branch.markAsDeleted('cycle-autofix');
logFix(`Branch '${branch.branchId}' between child '${noteId}' and parent '${parentNoteId}' has been deleted since it was causing a tree cycle.`);

this.unrecoveredConsistencyErrors = true;
return true;
}
else {
logError(`Tree cycle detected at parent-child relationship: ${parentNoteId} - ${noteId}, whole path: ${path}`);

this.unrecoveredConsistencyErrors = true;
}
} else {
const newPath = path.slice();
newPath.push(noteId);

checkTreeCycle(parentNoteId, newPath);
const retryNeeded = checkTreeCycle(parentNoteId, newPath);

if (retryNeeded) {
return true;
}
}
}

return false;
};

const noteIds = Object.keys(childToParents);

for (const noteId of noteIds) {
checkTreeCycle(noteId, []);
const retryNeeded = checkTreeCycle(noteId, []);

if (retryNeeded) {
return true;
}
}

return false;
}

checkAndRepairTreeCycles() {
let treeFixed = false;

while (this.checkTreeCycles()) {
// fixing cycle means deleting branches, we might need to create a new branch to recover the note
this.findExistencyIssues();

treeFixed = true;
}

if (childToParents['root'].length !== 1 || childToParents['root'][0] !== 'none') {
logError('Incorrect root parent: ' + JSON.stringify(childToParents['root']));
this.unrecoveredConsistencyErrors = true;
if (treeFixed) {
this.reloadNeeded = true;
}
}

Expand Down Expand Up @@ -646,7 +671,7 @@ class ConsistencyChecks {
if (!this.unrecoveredConsistencyErrors) {
// we run this only if basic checks passed since this assumes basic data consistency

this.checkTreeCycles();
this.checkAndRepairTreeCycles();
}

if (this.reloadNeeded) {
Expand Down

0 comments on commit 5dab189

Please sign in to comment.