From 6cac63e4e5058ce0f47528aa087107e985c7fab5 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 19 Dec 2019 17:14:00 +0100 Subject: [PATCH 1/2] pad.js: fix freeze on pad deletion when it has many revisions --- src/node/db/Pad.js | 13 +++++++------ src/node/utils/promises.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 src/node/utils/promises.js diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index cf016444cec..10f50ec2217 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -16,6 +16,7 @@ var readOnlyManager = require("./ReadOnlyManager"); var crypto = require("crypto"); var randomString = require("../utils/randomstring"); var hooks = require('ep_etherpad-lite/static/js/pluginfw/hooks'); +var promises = require('../utils/promises') // serialization/deserialization attributes var attributeBlackList = ["id"]; @@ -482,14 +483,14 @@ Pad.prototype.remove = async function remove() { db.remove("readonly2pad:" + readonlyID); // delete all chat messages - for (let i = 0, n = this.chatHead; i <= n; ++i) { - db.remove("pad:" + padID + ":chat:" + i); - } + promises.timesLimit(this.chatHead + 1, 500, function (i) { + return db.remove("pad:" + padID + ":chat:" + i); + }) // delete all revisions - for (let i = 0, n = this.head; i <= n; ++i) { - db.remove("pad:" + padID + ":revs:" + i); - } + promises.timesLimit(this.head + 1, 500, function (i) { + return db.remove("pad:" + padID + ":revs:" + i); + }) // remove pad from all authors who contributed this.getAllAuthors().forEach(authorID => { diff --git a/src/node/utils/promises.js b/src/node/utils/promises.js new file mode 100644 index 00000000000..4fb2e8318a4 --- /dev/null +++ b/src/node/utils/promises.js @@ -0,0 +1,32 @@ +/** + * Helpers to manipulate promises (like async but for promises). + */ + +var timesLimit = function (ltMax, concurrency, promiseCreator) { + var done = 0 + var current = 0 + + function addAnother () { + function _internalRun () { + done++ + + if (done < ltMax) { + addAnother() + } + } + + promiseCreator(current) + .then(_internalRun) + .catch(_internalRun) + + current++ + } + + for (var i = 0; i < concurrency && i < ltMax; i++) { + addAnother() + } +} + +module.exports = { + timesLimit: timesLimit +} From 2d5f5a06334a23d50dd526b7d43b9adb63a1317f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 10 Apr 2020 16:14:18 +0200 Subject: [PATCH 2/2] pad.js: wait write callback instead of buffer callback --- src/node/db/Pad.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node/db/Pad.js b/src/node/db/Pad.js index 10f50ec2217..158bfafb57c 100644 --- a/src/node/db/Pad.js +++ b/src/node/db/Pad.js @@ -484,12 +484,12 @@ Pad.prototype.remove = async function remove() { // delete all chat messages promises.timesLimit(this.chatHead + 1, 500, function (i) { - return db.remove("pad:" + padID + ":chat:" + i); + return db.remove("pad:" + padID + ":chat:" + i, null); }) // delete all revisions promises.timesLimit(this.head + 1, 500, function (i) { - return db.remove("pad:" + padID + ":revs:" + i); + return db.remove("pad:" + padID + ":revs:" + i, null); }) // remove pad from all authors who contributed