mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-02-01 03:12:42 +01:00
PadMessageHandler.js: further conversion
This commit is contained in:
parent
d543d5ae6a
commit
9246a1de26
1 changed files with 135 additions and 262 deletions
|
@ -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 = [];
|
||||||
|
|
Loading…
Reference in a new issue