Answer the question
In order to leave comments, you need to log in
What approach to messenger architecture is optimal?
We are writing a messenger for private use in our application. The planned load of the current version is hundreds of users, maybe a thousand or two.
1. I use Mongo as a database. Messages are written to messages (linked via chats_id to user_chats and uid to an external table in the users database). The arrival of a message on the client creates a flurry of events in response (marking as read). It is clear that you need to queue. How to do it better? Is there a way to prioritize queues?
2. How many users should the spherical process of a node in a vacuum withstand? How much memory does it consume? I use pm2 for process management and node-ipc for broadcast.
3. Where to turn, whom to ask to optimize queries to the database. Now there are hastily written constructions of the form:
const loadUserChatsStatistic = async (chatIds, userId) => {
const startExecTime = new Date();
const userChats = await db().collection('user_chats').aggregate([
{ $match: { uid: userId, chats_id: { $in: chatIds.map(ObjectID) } } },
{ $lookup: { from: 'chats', localField: 'chats_id', foreignField: '_id', as: 'chat' } },
{ $unwind: '$chat' },
{ $lookup: { from: 'user_last_seen', localField: 'chats_id', foreignField: 'chats_id', as: 'last_seens' } },
]).toArray();
const chats = await Promise.all(userChats.map(async (userChat) => {
const usersCount = await db().collection('user_chats')
.find({ chats_id: userChat.chats_id }).count();
let unreadCountQuery = {};
if (userChat.last_read) {
unreadCountQuery = { _id: { $gt: userChat.last_read } };
} else {
unreadCountQuery = { _id: { $gt: userChat._id } };
}
const unreadCount = await db().collection('messages')
.find({ ...unreadCountQuery, chats_id: userChat.chats_id }).count();
const message = await db().collection('messages')
.findOne({ chats_id: userChat.chats_id }, { sort: { _id: -1 } }) || {};
return { ...userChat, usersCount, unreadCount, message };
}));
console.log('Execution time for loadUserChatsStatistic', new Date() - startExecTime);
return chats.sort((a, b) => {
if (!a.message._id) {
return true;
}
if (!b.message._id) {
return false;
}
return new Date(ObjectID(a.message._id).getTimestamp()) < new Date(ObjectID(b.message._id).getTimestamp());
});
};
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question