Revert "PadMessageHandler: Use a `Map` for `sessioninfos`"

Switching to a Map broke ep_webrtc and maybe other plugins.

This reverts commit eeead46437.
pull/5024/head
Richard Hansen 2021-05-05 18:09:10 -04:00
parent 3c087af038
commit b040ebf419
2 changed files with 37 additions and 28 deletions

View File

@ -810,12 +810,15 @@ exports.createDiffHTML = async (padID, startRev, endRev) => {
exports.getStats = async () => {
const sessionInfos = padMessageHandler.sessioninfos;
const map = function* (it, fn) { for (const i of it) yield fn(i); };
const activePads = new Set(map(sessionInfos.values(), ({padId}) => padId));
const sessionKeys = Object.keys(sessionInfos);
const activePads = new Set(Object.entries(sessionInfos).map((k) => k[1].padId));
const {padIDs} = await padManager.listAllPads();
return {
totalPads: padIDs.length,
totalSessions: sessionInfos.size,
totalSessions: sessionKeys.length,
totalActivePads: activePads.size,
};
};

View File

@ -67,13 +67,13 @@ exports.socketio = () => {
* - readonly: Whether the client has read-only access (true) or read/write access (false).
* - rev: The last revision that was sent to the client.
*/
const sessioninfos = new Map();
const sessioninfos = {};
exports.sessioninfos = sessioninfos;
stats.gauge('totalUsers', () => Object.keys(socketio.sockets.sockets).length);
stats.gauge('activePads', () => {
const padIds = new Set();
for (const {padId} of sessioninfos.values()) {
for (const {padId} of Object.values(sessioninfos)) {
if (!padId) continue;
padIds.add(padId);
}
@ -106,7 +106,9 @@ exports.setSocketIO = (socket_io) => {
*/
exports.handleConnect = (socket) => {
stats.meter('connects').mark();
sessioninfos.set(socket.id, {});
// Initialize sessioninfos for this new session
sessioninfos[socket.id] = {};
};
/**
@ -128,7 +130,9 @@ exports.kickSessionsFromPad = (padID) => {
*/
exports.handleDisconnect = async (socket) => {
stats.meter('disconnects').mark();
const session = sessioninfos.get(socket.id);
// save the padname of this session
const session = sessioninfos[socket.id];
// if this connection was already etablished with a handshake,
// send a disconnect message to the others
@ -162,7 +166,9 @@ exports.handleDisconnect = async (socket) => {
// Allow plugins to hook into users leaving the pad
hooks.callAll('userLeave', session);
}
sessioninfos.delete(socket.id);
// Delete the sessioninfos entrys of this session
delete sessioninfos[socket.id];
};
/**
@ -193,7 +199,7 @@ exports.handleMessage = async (socket, message) => {
return;
}
const thisSession = sessioninfos.get(socket.id);
const thisSession = sessioninfos[socket.id];
if (!thisSession) {
messageLogger.warn('Dropped message from an unknown connection.');
@ -250,7 +256,7 @@ exports.handleMessage = async (socket, message) => {
}
// Drop the message if the client disconnected during the above processing.
if (sessioninfos.get(socket.id) !== thisSession) {
if (sessioninfos[socket.id] !== thisSession) {
messageLogger.warn('Dropping message from a connection that has gone away.');
return;
}
@ -295,7 +301,7 @@ exports.handleMessage = async (socket, message) => {
* @param message the message from the client
*/
const handleSaveRevisionMessage = async (socket, message) => {
const {padId, author: authorId} = sessioninfos.get(socket.id);
const {padId, author: authorId} = sessioninfos[socket.id];
const pad = await padManager.getPad(padId);
await pad.addSavedRevision(pad.head, authorId);
};
@ -345,7 +351,7 @@ exports.handleCustomMessage = (padID, msgString) => {
const handleChatMessage = async (socket, message) => {
const time = Date.now();
const text = message.data.text;
const {padId, author: authorId} = sessioninfos.get(socket.id);
const {padId, author: authorId} = sessioninfos[socket.id];
await exports.sendChatMessageToPadClients(time, authorId, text, padId);
};
@ -403,7 +409,7 @@ const handleGetChatMessages = async (socket, message) => {
return;
}
const {padId} = sessioninfos.get(socket.id);
const padId = sessioninfos[socket.id].padId;
const pad = await padManager.getPad(padId);
const chatMessages = await pad.getChatMessages(start, end);
@ -436,11 +442,11 @@ const handleSuggestUserName = (socket, message) => {
return;
}
const {padId} = sessioninfos.get(socket.id);
const padId = sessioninfos[socket.id].padId;
// search the author and send him this message
_getRoomSockets(padId).forEach((socket) => {
const session = sessioninfos.get(socket.id);
const session = sessioninfos[socket.id];
if (session && session.author === message.data.payload.unnamedId) {
socket.json.send(message);
}
@ -466,7 +472,7 @@ const handleUserInfoUpdate = async (socket, message) => {
}
// Check that we have a valid session and author to update.
const session = sessioninfos.get(socket.id);
const session = sessioninfos[socket.id];
if (!session || !session.author || !session.padId) {
messageLogger.warn(`Dropped message, USERINFO_UPDATE Session not ready.${message.data}`);
return;
@ -548,7 +554,7 @@ const handleUserChanges = async (socket, message) => {
// The client might disconnect between our callbacks. We should still
// finish processing the changeset, so keep a reference to the session.
const thisSession = sessioninfos.get(socket.id);
const thisSession = sessioninfos[socket.id];
// TODO: this might happen with other messages too => find one place to copy the session
// and always use the copy. atm a message will be ignored if the session is gone even
@ -710,7 +716,7 @@ exports.updatePadClients = async (pad) => {
const revCache = {};
await Promise.all(roomSockets.map(async (socket) => {
const sessioninfo = sessioninfos.get(socket.id);
const sessioninfo = sessioninfos[socket.id];
// The user might have disconnected since _getRoomSockets() was called.
if (sessioninfo == null) return;
@ -805,7 +811,7 @@ const _correctMarkersInPad = (atext, apool) => {
};
const handleSwitchToPad = async (socket, message, _authorID) => {
const currentSessionInfo = sessioninfos.get(socket.id);
const currentSessionInfo = sessioninfos[socket.id];
const padId = currentSessionInfo.padId;
// Check permissions for the new pad.
@ -824,20 +830,20 @@ const handleSwitchToPad = async (socket, message, _authorID) => {
assert(authorID === currentSessionInfo.author);
// Check if the connection dropped during the access check.
if (sessioninfos.get(socket.id) !== currentSessionInfo) return;
if (sessioninfos[socket.id] !== currentSessionInfo) return;
// clear the session and leave the room
_getRoomSockets(padId).forEach((socket) => {
const sinfo = sessioninfos.get(socket.id);
const sinfo = sessioninfos[socket.id];
if (sinfo && sinfo.author === currentSessionInfo.author) {
// fix user's counter, works on page refresh or if user closes browser window and then rejoins
sessioninfos.set(socket.id, {});
sessioninfos[socket.id] = {};
socket.leave(padId);
}
});
// start up the new pad
const newSessionInfo = sessioninfos.get(socket.id);
const newSessionInfo = sessioninfos[socket.id];
createSessionInfoAuth(newSessionInfo, message);
await handleClientReady(socket, message, authorID);
};
@ -921,17 +927,17 @@ const handleClientReady = async (socket, message, authorID) => {
// glue the clientVars together, send them and tell the other clients that a new one is there
// Check that the client is still here. It might have disconnected between callbacks.
const sessionInfo = sessioninfos.get(socket.id);
const sessionInfo = sessioninfos[socket.id];
if (sessionInfo == null) return;
// Check if this author is already on the pad, if yes, kick the other sessions!
const roomSockets = _getRoomSockets(pad.id);
for (const socket of roomSockets) {
const sinfo = sessioninfos.get(socket.id);
const sinfo = sessioninfos[socket.id];
if (sinfo && sinfo.author === authorID) {
// fix user's counter, works on page refresh or if user closes browser window and then rejoins
sessioninfos.set(socket.id, {});
sessioninfos[socket.id] = {};
socket.leave(padIds.padId);
socket.json.send({disconnect: 'userdup'});
}
@ -1145,7 +1151,7 @@ const handleClientReady = async (socket, message, authorID) => {
// Since sessioninfos might change while being enumerated, check if the
// sessionID is still assigned to a valid session
const sessionInfo = sessioninfos.get(roomSocket.id);
const sessionInfo = sessioninfos[roomSocket.id];
if (sessionInfo == null) return;
// get the authorname & colorId
@ -1427,7 +1433,7 @@ exports.padUsers = async (padID) => {
// iterate over all clients (in parallel)
await Promise.all(_getRoomSockets(padID).map(async (roomSocket) => {
const s = sessioninfos.get(roomSocket.id);
const s = sessioninfos[roomSocket.id];
if (s) {
const author = await authorManager.getAuthor(s.author);
// Fixes: https://github.com/ether/etherpad-lite/issues/4120