PadMessageHandler: Accept retransmissions of USER_CHANGES

pull/5328/head
Richard Hansen 2021-12-12 18:19:36 -05:00
parent a370cfa5c6
commit cff089e54e
3 changed files with 10 additions and 13 deletions

View File

@ -615,19 +615,15 @@ const handleUserChanges = async (socket, message) => {
// Update the changeset so that it can be applied to the latest revision.
while (r < pad.getHeadRevisionNumber()) {
r++;
const c = await pad.getRevisionChangeset(r);
const {changeset: c, meta: {author: authorId}} = await pad.getRevision(r);
if (changeset === c && thisSession.author === authorId) {
// Assume this is a retransmission of an already applied changeset.
rebasedChangeset = Changeset.identity(Changeset.unpack(changeset).oldLen);
}
// At this point, both "c" (from the pad) and "changeset" (from the
// client) are relative to revision r - 1. The follow function
// rebases "changeset" so that it is relative to revision r
// and can be applied after "c".
// a changeset can be based on an old revision with the same changes in it
// prevent eplite from accepting it TODO: better send the client a NEW_CHANGES
// of that revision
if (baseRev + 1 === r && c === changeset) throw new Error('Changeset already accepted');
rebasedChangeset = Changeset.follow(c, rebasedChangeset, false, pad.pool);
}

View File

@ -208,8 +208,9 @@ const getCollabClient = (ace2editor, serverVars, initialUserInfo, options, _pad)
} else if (msg.type === 'ACCEPT_COMMIT') {
serverMessageTaskQueue.enqueue(() => {
const {newRev} = msg;
// newRev will equal rev if the changeset has no net effect (identity changeset, or removing
// and re-adding the same characters with the same attributes).
// newRev will equal rev if the changeset has no net effect (identity changeset, removing
// and re-adding the same characters with the same attributes, or retransmission of an
// already applied changeset).
if (![rev, rev + 1].includes(newRev)) {
window.console.warn(`bad message revision on ACCEPT_COMMIT: ${newRev} not ${rev + 1}`);
// setChannelState("DISCONNECTED", "badmessage_acceptcommit");

View File

@ -75,12 +75,12 @@ describe(__filename, function () {
await assertRejected();
});
it('retransmission is rejected', async function () {
it('retransmission is accepted, has no effect', async function () {
sendUserChanges('Z:1>5+5$hello');
await assertAccepted(rev + 1);
--rev;
sendUserChanges('Z:1>5+5$hello');
await assertRejected();
await assertAccepted(rev + 1);
assert.equal(pad.text(), 'hello\n');
});