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