@phenomlab said in NodeBB Global Tchat : Forum with many users performance issues:
I’d say that this was still relevant, and would solve the short term issue (in most cases) but if anything, you’ll still experience slowness if you have say 600 users online.
The right way to handle this in my view would be to pass the notification stream to a message queuing service (like RabbitMQ or Redis) and let that process in the back end rather than cause locking on the forum itself. I’m surprised that this is in fact the case as standard emails are being queued and aren’t sent in real time.
I personally don’t use this plugin as you know, so I’d need to review the code first in order to understand it’s structure.
Thank you for your analyse
I would have liked to try the thing all the same, just to see the result
600 users is better than 4000
Here is the content of the /src/messsagin/notification.js file
I put it here because I don’t see where to integrate the given code for test :
'use strict';
const winston = require('winston');
const user = require('../user');
const notifications = require('../notifications');
const sockets = require('../socket.io');
const plugins = require('../plugins');
const meta = require('../meta');
module.exports = function (Messaging) {
Messaging.notifyQueue = {}; // Only used to notify a user of a new chat message, see Messaging.notifyUser
Messaging.notifyUsersInRoom = async (fromUid, roomId, messageObj) => {
let uids = await Messaging.getUidsInRoom(roomId, 0, -1);
uids = await user.blocks.filterUids(fromUid, uids);
let data = {
roomId: roomId,
fromUid: fromUid,
message: messageObj,
uids: uids,
};
data = await plugins.hooks.fire('filter:messaging.notify', data);
if (!data || !data.uids || !data.uids.length) {
return;
}
uids = data.uids;
uids.forEach((uid) => {
data.self = parseInt(uid, 10) === parseInt(fromUid, 10) ? 1 : 0;
Messaging.pushUnreadCount(uid);
sockets.in(`uid_${uid}`).emit('event:chats.receive', data);
});
if (messageObj.system) {
return;
}
// Delayed notifications
let queueObj = Messaging.notifyQueue[`${fromUid}:${roomId}`];
if (queueObj) {
queueObj.message.content += `\n${messageObj.content}`;
clearTimeout(queueObj.timeout);
} else {
queueObj = {
message: messageObj,
};
Messaging.notifyQueue[`${fromUid}:${roomId}`] = queueObj;
}
queueObj.timeout = setTimeout(async () => {
try {
await sendNotifications(fromUid, uids, roomId, queueObj.message);
} catch (err) {
winston.error(`[messaging/notifications] Unabled to send notification\n${err.stack}`);
}
}, meta.config.notificationSendDelay * 1000);
};
async function sendNotifications(fromuid, uids, roomId, messageObj) {
const isOnline = await user.isOnline(uids);
uids = uids.filter((uid, index) => !isOnline[index] && parseInt(fromuid, 10) !== parseInt(uid, 10));
if (!uids.length) {
return;
}
const { displayname } = messageObj.fromUser;
const isGroupChat = await Messaging.isGroupChat(roomId);
const notification = await notifications.create({
type: isGroupChat ? 'new-group-chat' : 'new-chat',
subject: `[[email:notif.chat.subject, ${displayname}]]`,
bodyShort: `[[notifications:new_message_from, ${displayname}]]`,
bodyLong: messageObj.content,
nid: `chat_${fromuid}_${roomId}`,
from: fromuid,
path: `/chats/${messageObj.roomId}`,
});
delete Messaging.notifyQueue[`${fromuid}:${roomId}`];
notifications.push(notification, uids);
}
};