PadMessageHandler.js: further conversion

This commit is contained in:
Ray Bellis 2019-01-30 13:55:49 +00:00
parent d543d5ae6a
commit 9246a1de26

View file

@ -1274,7 +1274,7 @@ async function handleClientReady(client, message)
/** /**
* Handles a request for a rough changeset, the timeslider client needs it * Handles a request for a rough changeset, the timeslider client needs it
*/ */
function handleChangesetRequest(client, message) async function handleChangesetRequest(client, message)
{ {
// check if all ok // check if all ok
if (message.data == null) { if (message.data == null) {
@ -1308,309 +1308,182 @@ function handleChangesetRequest(client, message)
return; return;
} }
var granularity = message.data.granularity; let granularity = message.data.granularity;
var start = message.data.start; let start = message.data.start;
var end = start + (100 * granularity); let end = start + (100 * granularity);
var padIds;
async.series([ let padIds = await readOnlyManager.getIds(message.padId);
function(callback) {
readOnlyManager.getIds(message.padId, function(err, value) {
if (ERR(err, callback)) return;
padIds = value;
callback();
});
},
function(callback) {
// build the requested rough changesets and send them back // build the requested rough changesets and send them back
getChangesetInfo(padIds.padId, start, end, granularity, function(err, changesetInfo) { try {
if (err) return console.error('Error while handling a changeset request for ' + padIds.padId, err, message.data); let data = await getChangesetInfo(padIds.padId, start, end, granularity);
var data = changesetInfo;
data.requestID = message.data.requestID; data.requestID = message.data.requestID;
client.json.send({ type: "CHANGESET_REQ", data });
client.json.send({ type: "CHANGESET_REQ", data: data }); } catch (err) {
}); console.error('Error while handling a changeset request for ' + padIds.padId, err, message.data);
} }
]);
} }
/** /**
* Tries to rebuild the getChangestInfo function of the original Etherpad * Tries to rebuild the getChangestInfo function of the original Etherpad
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L144 * https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L144
*/ */
let getChangesetInfo = thenify(function getChangesetInfo(padId, startNum, endNum, granularity, callback) async function getChangesetInfo(padId, startNum, endNum, granularity)
{ {
var forwardsChangesets = []; let pad = await padManager.getPad(padId);
var backwardsChangesets = []; let head_revision = pad.getHeadRevisionNumber();
var timeDeltas = [];
var apool = new AttributePool();
var pad;
var composedChangesets = {};
var revisionDate = [];
var lines;
var head_revision = 0;
async.series([
// get the pad from the database
function(callback) {
padManager.getPad(padId, function(err, _pad) {
if (ERR(err, callback)) return;
pad = _pad;
head_revision = pad.getHeadRevisionNumber();
callback();
});
},
function(callback) {
// calculate the last full endnum // calculate the last full endnum
var lastRev = pad.getHeadRevisionNumber(); if (endNum > head_revision + 1) {
if (endNum > lastRev + 1) { endNum = head_revision + 1;
endNum = lastRev + 1;
} }
endNum = Math.floor(endNum / granularity) * granularity; endNum = Math.floor(endNum / granularity) * granularity;
var compositesChangesetNeeded = []; let compositesChangesetNeeded = [];
var revTimesNeeded = []; let revTimesNeeded = [];
// figure out which composite Changeset and revTimes we need, to load them in bulk // figure out which composite Changeset and revTimes we need, to load them in bulk
var compositeStart = startNum; for (let start = startNum; start < endNum; start += granularity) {
while (compositeStart < endNum) { let end = start + granularity;
var compositeEnd = compositeStart + granularity;
// add the composite Changeset we needed // add the composite Changeset we needed
compositesChangesetNeeded.push({ start: compositeStart, end: compositeEnd }); compositesChangesetNeeded.push({ start, end });
// add the t1 time we need // add the t1 time we need
revTimesNeeded.push(compositeStart == 0 ? 0 : compositeStart - 1); revTimesNeeded.push(start == 0 ? 0 : start - 1);
// add the t2 time we need // add the t2 time we need
revTimesNeeded.push(compositeEnd - 1); revTimesNeeded.push(end - 1);
compositeStart += granularity;
} }
// get all needed db values parallel // get all needed db values parallel - no await here since
async.parallel([ // it would make all the lookups run in series
function(callback) {
// get all needed composite Changesets // get all needed composite Changesets
async.forEach(compositesChangesetNeeded, function(item, callback) { let composedChangesets = {};
composePadChangesets(padId, item.start, item.end, function(err, changeset) { let p1 = Promise.all(compositesChangesetNeeded.map(item => {
if (ERR(err, callback)) return; return composePadChangesets(padId, item.start, item.end).then(changeset => {
composedChangesets[item.start + "/" + item.end] = changeset; composedChangesets[item.start + "/" + item.end] = changeset;
callback();
}); });
}, callback); }));
},
function(callback) {
// get all needed revision Dates // get all needed revision Dates
async.forEach(revTimesNeeded, function(revNum, callback) { let revisionDate = [];
pad.getRevisionDate(revNum, function(err, revDate) { let p2 = Promise.all(revTimesNeeded.map(revNum => {
if (ERR(err, callback)) return; return pad.getRevisionDate(revNum).then(revDate => {
revisionDate[revNum] = Math.floor(revDate / 1000);
revisionDate[revNum] = Math.floor(revDate/1000);
callback();
}); });
}, callback); }));
},
// get the lines // get the lines
function(callback) { let lines;
getPadLines(padId, startNum-1, function(err, _lines) { let p3 = getPadLines(padId, startNum - 1).then(_lines => {
if (ERR(err, callback)) return;
lines = _lines; lines = _lines;
callback();
}); });
}
], callback);
},
// don't know what happens here exactly :/ // wait for all of the above to complete
function(callback) { await Promise.all([p1, p2, p3]);
var compositeStart = startNum;
while (compositeStart < endNum) { // doesn't know what happens here exactly :/
var compositeEnd = compositeStart + granularity; let timeDeltas = [];
if (compositeEnd > endNum || compositeEnd > head_revision+1) { let forwardsChangesets = [];
let backwardsChangesets = [];
let apool = new AttributePool();
for (let compositeStart = startNum; compositeStart < endNum; compositeStart += granularity) {
let compositeEnd = compositeStart + granularity;
if (compositeEnd > endNum || compositeEnd > head_revision + 1) {
break; break;
} }
var forwards = composedChangesets[compositeStart + "/" + compositeEnd]; let forwards = composedChangesets[compositeStart + "/" + compositeEnd];
var backwards = Changeset.inverse(forwards, lines.textlines, lines.alines, pad.apool()); let backwards = Changeset.inverse(forwards, lines.textlines, lines.alines, pad.apool());
Changeset.mutateAttributionLines(forwards, lines.alines, pad.apool()); Changeset.mutateAttributionLines(forwards, lines.alines, pad.apool());
Changeset.mutateTextLines(forwards, lines.textlines); Changeset.mutateTextLines(forwards, lines.textlines);
var forwards2 = Changeset.moveOpsToNewPool(forwards, pad.apool(), apool); let forwards2 = Changeset.moveOpsToNewPool(forwards, pad.apool(), apool);
var backwards2 = Changeset.moveOpsToNewPool(backwards, pad.apool(), apool); let backwards2 = Changeset.moveOpsToNewPool(backwards, pad.apool(), apool);
var t1, t2; let t1 = (compositeStart == 0) ? revisionDate[0] : revisionDate[compositeStart - 1];
if (compositeStart == 0) { let t2 = revisionDate[compositeEnd - 1];
t1 = revisionDate[0];
} else {
t1 = revisionDate[compositeStart - 1];
}
t2 = revisionDate[compositeEnd - 1];
timeDeltas.push(t2 - t1); timeDeltas.push(t2 - t1);
forwardsChangesets.push(forwards2); forwardsChangesets.push(forwards2);
backwardsChangesets.push(backwards2); backwardsChangesets.push(backwards2);
compositeStart += granularity;
} }
callback(); return { forwardsChangesets, backwardsChangesets,
} apool: apool.toJsonable(), actualEndNum: endNum,
], timeDeltas, start: startNum, granularity };
function(err) { }
if (ERR(err, callback)) return;
callback(null, {forwardsChangesets: forwardsChangesets,
backwardsChangesets: backwardsChangesets,
apool: apool.toJsonable(),
actualEndNum: endNum,
timeDeltas: timeDeltas,
start: startNum,
granularity: granularity });
});
});
/** /**
* Tries to rebuild the getPadLines function of the original Etherpad * Tries to rebuild the getPadLines function of the original Etherpad
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L263 * https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L263
*/ */
let getPadLines = thenify(function getPadLines(padId, revNum, callback) async function getPadLines(padId, revNum)
{ {
var atext; let pad = padManager.getPad(padId);
var result = {};
var pad;
async.series([
// get the pad from the database
function(callback) {
padManager.getPad(padId, function(err, _pad) {
if (ERR(err, callback)) return;
pad = _pad;
callback();
});
},
// get the atext // get the atext
function(callback) { let atext;
if (revNum >= 0) {
pad.getInternalRevisionAText(revNum, function(err, _atext) {
if (ERR(err, callback)) return;
atext = _atext; if (revNum >= 0) {
callback(); atext = await pad.getInternalRevisionAText(revNum);
});
} else { } else {
atext = Changeset.makeAText("\n"); atext = Changeset.makeAText("\n");
callback(null);
} }
},
function(callback) { return {
result.textlines = Changeset.splitTextLines(atext.text); textlines: Changeset.splitTextLines(atext.text),
result.alines = Changeset.splitAttributionLines(atext.attribs, atext.text); alines: Changeset.splitAttributionLines(atext.attribs, atext.text)
callback(null); };
} }
],
function(err) {
if (ERR(err, callback)) return;
callback(null, result);
});
});
/** /**
* Tries to rebuild the composePadChangeset function of the original Etherpad * Tries to rebuild the composePadChangeset function of the original Etherpad
* https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L241 * https://github.com/ether/pad/blob/master/etherpad/src/etherpad/control/pad/pad_changeset_control.js#L241
*/ */
let composePadChangesets = thenify(function(padId, startNum, endNum, callback) async function composePadChangesets (padId, startNum, endNum)
{ {
var pad; let pad = await padManager.getPad(padId);
var changesets = {};
var changeset;
async.series([
// get the pad from the database
function(callback) {
padManager.getPad(padId, function(err, _pad) {
if (ERR(err, callback)) return;
pad = _pad;
callback();
});
},
// fetch all changesets we need // fetch all changesets we need
function(callback) { let headNum = pad.getHeadRevisionNumber();
var changesetsNeeded=[]; endNum = Math.min(endNum, headNum + 1);
startNum = Math.max(startNum, 0);
var headNum = pad.getHeadRevisionNumber();
if (endNum > headNum + 1) {
endNum = headNum + 1;
}
if (startNum < 0) {
startNum = 0;
}
// create an array for all changesets, we will // create an array for all changesets, we will
// replace the values with the changeset later // replace the values with the changeset later
for (var r = startNum; r < endNum; r++) { let changesetsNeeded = [];
for (let r = startNum ; r < endNum; r++) {
changesetsNeeded.push(r); changesetsNeeded.push(r);
} }
// get all changesets // get all changesets
async.forEach(changesetsNeeded, function(revNum,callback) { let changesets = {};
pad.getRevisionChangeset(revNum, function(err, value) { await Promise.all(changesetsNeeded.map(revNum => {
if (ERR(err, callback)) return; return pad.getRevisionChangeset(revNum).then(changeset => changesets[revNum] = changeset);
}));
changesets[revNum] = value;
callback();
});
},callback);
},
// compose Changesets // compose Changesets
function(callback) {
changeset = changesets[startNum];
var pool = pad.apool();
try { try {
for (var r = startNum + 1; r < endNum; r++) { let changeset = changesets[startNum];
var cs = changesets[r]; let pool = pad.apool();
for (let r = startNum + 1; r < endNum; r++) {
let cs = changesets[r];
changeset = Changeset.compose(changeset, cs, pool); changeset = Changeset.compose(changeset, cs, pool);
} }
} catch(e) { return changeset;
} catch (e) {
// r-1 indicates the rev that was build starting with startNum, applying startNum+1, +2, +3 // r-1 indicates the rev that was build starting with startNum, applying startNum+1, +2, +3
console.warn("failed to compose cs in pad:", padId, " startrev:", startNum, " current rev:", r); console.warn("failed to compose cs in pad:", padId, " startrev:", startNum," current rev:", r);
return callback(e); throw e;
} }
}
callback(null);
}
],
// return err and changeset
function(err) {
if (ERR(err, callback)) return;
callback(null, changeset);
});
});
function _getRoomClients(padID) { function _getRoomClients(padID) {
var roomClients = []; var roomClients = [];