From 082caf98e809bf3dc6a18edb6c26750f61015522 Mon Sep 17 00:00:00 2001 From: zadam Date: Fri, 13 Jan 2023 11:53:25 +0100 Subject: [PATCH] restore all "named" notes quickly after their deletion, #3517 --- src/services/handlers.js | 12 ++++++++++++ src/services/one_time_timer.js | 25 +++++++++++++++++++++++++ src/services/special_notes.js | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/services/one_time_timer.js diff --git a/src/services/handlers.js b/src/services/handlers.js index fc67b464f..98fc873dd 100644 --- a/src/services/handlers.js +++ b/src/services/handlers.js @@ -4,6 +4,8 @@ const treeService = require('./tree'); const noteService = require('./notes'); const becca = require('../becca/becca'); const Attribute = require('../becca/entities/attribute'); +const hiddenSubtreeService = require("./hidden_subtree"); +const oneTimeTimer = require("./one_time_timer"); function runAttachedRelations(note, relationName, originEntity) { if (!note) { @@ -206,6 +208,16 @@ eventService.subscribe(eventService.ENTITY_DELETED, ({ entityName, entity }) => if (entityName === 'branches') { runAttachedRelations(entity.getNote(), 'runOnBranchDeletion', entity); } + + if (entityName === 'notes' && entity.noteId.startsWith("_")) { + // "named" note has been deleted, we will probably need to rebuild the hidden subtree + // scheduling so that bulk deletes won't trigger so many checks + oneTimeTimer.scheduleExecution('hidden-subtree-check', 1000, () => { + console.log("Checking hidden subtree"); + + hiddenSubtreeService.checkHiddenSubtree(); + }); + } }); module.exports = { diff --git a/src/services/one_time_timer.js b/src/services/one_time_timer.js new file mode 100644 index 000000000..68b4dfef4 --- /dev/null +++ b/src/services/one_time_timer.js @@ -0,0 +1,25 @@ +const scheduledExecutions = {}; + +/** + * Subsequent calls will not move the timer to future. The first caller determines the time of execution. + * + * The good thing about synchronous better-sqlite3 is that this cannot interrupt transaction. The execution will be called + * only outside of a transaction. + */ +function scheduleExecution(name, milliseconds, cb) { + if (name in scheduledExecutions) { + return; + } + + scheduledExecutions[name] = true; + + setTimeout(() => { + delete scheduledExecutions[name]; + + cb(); + }, milliseconds); +} + +module.exports = { + scheduleExecution +}; \ No newline at end of file diff --git a/src/services/special_notes.js b/src/services/special_notes.js index ee88a48eb..bbc1bc978 100644 --- a/src/services/special_notes.js +++ b/src/services/special_notes.js @@ -218,7 +218,7 @@ function resetLauncher(noteId) { log.info(`Note ${noteId} is not a resettable launcher note.`); } - hiddenSubtreeService.checkHiddenSubtree(); + // the re-building deleted launchers will be done in handlers } /**