Executando verificação de segurança...
1

Chat - Notificação de nova mensagem

Atualmente tenho um projeto em Node onde é um chat e agora estou desenvolvendo notificações de mensagens.

Tenho esse código abaixo que é executado sempre que uma nova mensagem é recebida (basicamente tenho um usuário onde faz relação com um chat, e sempre que recebo uma nova mensagem ele executa o código abaixo, buscando o chat que teve a mensagem e salvando no banco os dados atualizados, sendo o essencial o unread_count pra verificar quantas mensagens não foram lidas e após enviando um evento com socket pro cliente):

const update: EventsHandler<'new:message'> = async (updates: ChatUpdate[]) => {
		for (const update of updates) {
			try {
				const data = transformDataOnStore(update);

				let chat = await Chat.query().where('id', data.id).first();

				if (chat) {
					data['unread_count'] = typeof data.unread_count === 'number' ? chat.unread_count + data.unread_count : 0;
					chat = await chat.merge({...data, unread_count: data.unread_count}).save();
				} else {
					chat = await Chat.create(data);
				}

				socket.emit('update:chat', chat);
			} catch (error) {
				Logger.error({ error }, 'ERROR X');
			}
		}
	};

Qual a forma mais otimizada pra fazer isso? Acredito que conforme muitos usuários trocam mensagens, salvar diretamente no banco novamente quando uma nova mensagem é recebida não seja a melhor forma, pois vai demandar muito processamento do banco de dados (atualmente o PostgreSQL).

Pensei na solução de não salvar no SQL, mas sim no Redis, o que recomendam?

Carregando publicação patrocinada...
1

Se tiver muita escrita, muita mesmo, eu iria de noSql, mongo, dynamoDB.... vai depender de suas regras, se não vai haver muitos relacionamentos. Usa redis também, para salvar por exemplo a sessão do usuário ou ás 30 últimas mensagens assim que abrimos o chat, caso o usuário role o chat para ver ás mais antigas ai você consulta no banco. Você também pode usar filas para ir processando as menssagens em segundo plano, não necessáriamente na hora, mas quando der, tendo a possíbilidade de engatilhar novos eventos.

1

Para ajudar preciso de mais informações:

Quantas mensagens ficam salvas no banco de dados?

Fica salvo todo o histórico da conversa ou somente as mensagens não lidas?

Como você salva as mensagens? (Qual é a estrutura?)

1

Tenho a seguinte estrutura de tabelas:
messages, contacts e chats.

Ao começar conversar com um contato automaticamente é criado um chat (pra salvar algumas informações relevantes, como por exemplo o unread_count) vinculado ao contato e a cada mensagem enviada pro contato ou recebida dele é salvo na tabela messages.

Quantas mensagens ficam salvas no banco de dados?
Todas as mensagens enviadas/recebidas.

Fica salvo todo o histórico da conversa ou somente as mensagens não lidas?
Todo o histórico.

Como você salva as mensagens? (Qual é a estrutura?)
Mencionei no começo, embora eu acredite que seja irrelevante nesse caso pois as notificações de mensagens não lidas chegam por um evento de socket de um sistema terceiro e tudo é armazenado na tabela chat, não messages.

2

Pensei na solução de não salvar no SQL, mas sim no Redis, o que recomendam?

Redis ao reiniciar perde todas as informações. Seria uma boa opção salvar nele se a consulta você precisa fazer muito mais que a gravação. Aí o fluxo ideal seria salvar no banco de dados, salvar no redis e consultar primeiro no redis, e se não encontrar no banco de dados.

Agora caso a escrita seja muito mais frequente que a leitura não vejo uma otimização que seja muito útil

1

No meu caso a escrita é muito mais frequente que a leitura (toda nova mensagem vou fazer uma consulta pra buscar o chat e outra pra atualizar, emitindo o socket da notificação pro cliente. A leitura só será feita quando o usuário atualizar a tela).

Então não teria muito o que fazer?

1
1
1

se o campo id é unico, acredito que vc consegue usar um .get() direto ao inves de .firt() (se olhar a consulta, nao precisa so "LIMIT 1" gerado pelo first)