PadMessageHandler: Accept retransmissions of USER_CHANGES
parent
a370cfa5c6
commit
cff089e54e
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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');
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue