Как предотвратить несоответствие данных с приложением чата в MongoDB? - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть приложение чата, использующее node.js и socket.io, которое хранит информацию о пользователях в Redis и MongoDB. Когда пользователь впервые подключается к серверу сокетов, для него создается идентификатор пользователя, и этот идентификатор (вместе с его именем пользователя) сохраняется в объекте сокета. Полная информация о пользователе (включая аватар, электронную почту и т. Д. c) хранится в MongoDB, а часть также кэшируется в Redis. Когда клиент отключается от сервера сокетов, событие обрабатывается следующим обработчиком событий:

const handleDisconnect = async () => {
  const {userId, username} = socket;
  if (userId && username) {
    try {
      delete socket.userId;
      delete socket.username;

      await redisClient.del(`user:${userId}`);

      await User.findByIdAndDelete(userId);
    } catch (err) {
      console.log(err);
    }
  }
};

Теперь, поскольку команды, удаляющие пользователя из Redis и Mon go, являются асинхронными c, по крайней мере в теории есть вероятность, что они могут бросить. Например, если команда удаления из Redis выбрасывает, то приведенная ниже команда не будет запущена, и пользователь не будет удален из MongoDB.

То же самое может произойти даже при добавлении пользователя в эти базы данных в первую очередь, так как команды базы данных всегда могут теоретически не выполняться и приводить вещи в несогласованное состояние.

Существует ли стандартный способ обработки таких ситуаций?

Должен ли я реализовать лучшую обработку исключений, чтобы я перехватывал все возможные ошибки и продолжал повторять попытки выполнения команд базы данных, пока они не будут выполнены успешно?

Или я должен реализовать какую-то сборку мусора, которая периодически проходит через базы данных и очищает документы, которые не были успешно удалены?

1 Ответ

0 голосов
/ 28 апреля 2020

Должен ли я реализовать лучшую обработку исключений, чтобы перехватывать все возможные ошибки

Если каждая из команд в вашем блоке try-catch может завершиться неудачно, и вы, как правило, хотите выполнить все из них я, конечно, добавил бы блок try-catch вокруг каждой команды, а не всех вместе.

Один из подходов, который вы можете рассмотреть, - это сохранить одно значение в redis, которое указывает, является ли остальные данные (полностью) там, например, ID пользователя / имя пользователя. При записи данных в Redis установите это значение последним. При очистке сначала удалите его. При чтении из Redis проверьте, присутствует ли это значение, затем продолжите чтение других данных. Таким образом, вы можете иметь частичные данные в redis, но ваше приложение не будет пытаться работать с ними.

В любом кеше существует вероятность того, что кеш устарел. Вы также можете рассмотреть, какие операции требуют обновления данных (например, аутентификация), а какие - нет (например, отображение # новых сообщений). Последний часто может терпеть некоторую застоя. Точная степень зависит от приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...