From b040ebf41932d8d74e089abdcad6ad1fdb1bee37 Mon Sep 17 00:00:00 2001 From: Richard Hansen Date: Wed, 5 May 2021 18:09:10 -0400 Subject: [PATCH] Revert "PadMessageHandler: Use a `Map` for `sessioninfos`" Switching to a Map broke ep_webrtc and maybe other plugins. This reverts commit eeead4643792d2e7a10aef935112bab8e620375c. --- src/node/db/API.js | 9 +++-- src/node/handler/PadMessageHandler.js | 56 +++++++++++++++------------ 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/node/db/API.js b/src/node/db/API.js index 01edf5e70..c262e078b 100644 --- a/src/node/db/API.js +++ b/src/node/db/API.js @@ -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, }; }; diff --git a/src/node/handler/PadMessageHandler.js b/src/node/handler/PadMessageHandler.js index a39cebe2a..899991a11 100644 --- a/src/node/handler/PadMessageHandler.js +++ b/src/node/handler/PadMessageHandler.js @@ -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