PadMessageHandler: Assume sessioninfo stays valid during client update

...but add a try/catch around the message transmission just in case.
This commit is contained in:
Richard Hansen 2021-04-12 23:49:24 -04:00
parent c85391862b
commit 770755debf

View file

@ -715,13 +715,13 @@ exports.updatePadClients = async (pad) => {
// but benefit of reusing cached revision object is HUGE // but benefit of reusing cached revision object is HUGE
const revCache = {}; const revCache = {};
// go through all sessions on this pad socket: for (const socket of roomSockets) {
for (const socket of roomSockets) { const sessioninfo = sessioninfos[socket.id];
const sid = socket.id; // The user might have disconnected since _getRoomSockets() was called.
if (sessioninfo == null) continue;
// send them all new changesets while (sessioninfo.rev < pad.getHeadRevisionNumber()) {
while (sessioninfos[sid] && sessioninfos[sid].rev < pad.getHeadRevisionNumber()) { const r = sessioninfo.rev + 1;
const r = sessioninfos[sid].rev + 1;
let revision = revCache[r]; let revision = revCache[r];
if (!revision) { if (!revision) {
revision = await pad.getRevision(r); revision = await pad.getRevision(r);
@ -732,24 +732,29 @@ exports.updatePadClients = async (pad) => {
const revChangeset = revision.changeset; const revChangeset = revision.changeset;
const currentTime = revision.meta.timestamp; const currentTime = revision.meta.timestamp;
// Re-check sessioninfos in case the client disconnected during the above await. let msg;
const sessioninfo = sessioninfos[sid];
if (sessioninfo == null) continue;
if (author === sessioninfo.author) { if (author === sessioninfo.author) {
socket.json.send({type: 'COLLABROOM', data: {type: 'ACCEPT_COMMIT', newRev: r}}); msg = {type: 'COLLABROOM', data: {type: 'ACCEPT_COMMIT', newRev: r}};
} else { } else {
const forWire = Changeset.prepareForWire(revChangeset, pad.pool); const forWire = Changeset.prepareForWire(revChangeset, pad.pool);
const wireMsg = {type: 'COLLABROOM', msg = {
data: {type: 'NEW_CHANGES', type: 'COLLABROOM',
data: {
type: 'NEW_CHANGES',
newRev: r, newRev: r,
changeset: forWire.translated, changeset: forWire.translated,
apool: forWire.pool, apool: forWire.pool,
author, author,
currentTime, currentTime,
timeDelta: currentTime - sessioninfo.time}}; timeDelta: currentTime - sessioninfo.time,
},
socket.json.send(wireMsg); };
}
try {
socket.json.send(msg);
} catch (err) {
messageLogger.error(`Failed to notify user of new revision: ${err.stack || err}`);
continue socket;
} }
sessioninfo.time = currentTime; sessioninfo.time = currentTime;
sessioninfo.rev = r; sessioninfo.rev = r;