При разработке высоконагруженных веб-приложений для лучшего масштабирования часто используется такой принцип, как CQRS. В нем говорится, что метод должен быть либо командой, выполняющей какое-то действие, либо запросом, возвращающим данные, но не тем и другим.
Другими словами, обращение к системе не должно изменить ответ. Более формально, только чистые методы, не имеющие побочных эффектов, могут возвращать значение.
Но для хорошего масштабирования разделения API на чтение/запись недостаточно.
Необходимо разделить базы данных, с которыми работает это API. Здесь нам на помощь приходит EventSourcing. Он предлагает хранить все системные события в одной базе данных, назовем ее EventStore, и строить на ее основе все остальные базы и таблицы.
Комбинация CQRS и EventSourcing существенно развязывает руки в плане балансировки нагрузки внутри системы, количества ее узлов, количества вспомогательных баз данных, использования кэширования и прочего, но в то же время усложняет логику работы.
приложение и вводит множество ограничений.
В этой статье мы рассмотрим один из нюансов проектирования клиентской части такой системы — оптимистичные обновления пользовательского интерфейса.
Для фронтенда возьмем модные React и Redux. Кстати, Redux и EventSourcing — очень похожие технологии.
Оптимистичные обновления пользовательского интерфейса уже сложно внедрить, а CQRS и EventSourcing еще больше усложняют задачу.
Как это должно работать? Давайте разберемся в этом шаг за шагом.
- Отправляем команду и, не дожидаясь ответа, отправляем оптимистичное событие в Redux Store. Оптимистическое событие будет содержать ожидаемые результаты сервера.
Также на этом шаге мы запоминаем текущее состояние данных, которое изменится при событии.
- Ждем результата отправки команды.
Если команда завершается неудачно, диспетчер событий откатывает оптимистическое обновление на основе данных, которые были запомнены на первом этапе.
Если все в порядке, то ничего не делаем.
- Ждём, когда настоящее событие приедет из автобуса к клиенту.
Когда это происходит, мы откатываем оптимистическое обновление и используем реальное событие.
Успех | Отказ |
---|---|
|
|
|
|
Посмотреть, как все работает вживую, можно здесь: Заключение Оптимистичные обновления пользовательского интерфейса могут значительно улучшить скорость реагирования вашего приложения.const optimisticCalculateNextHashMiddleware = (store) => { const tempHashes = {}; const api = createApi(store); return next => action => { switch (action.type) { case SEND_COMMAND_UPDATE_HASH_REQUEST: { const { aggregateId, hash } = action; // Save the previous data const { hashes } = store.getState() const prevHash = hashes[aggregateId].
hash; tempHashes[aggregateId] = prevHash // Dispatch an optimistic action store.dispatch({ type: OPTIMISTIC_HASH_UPDATED, aggregateId, hash }); // Send a command api.sendCommandCalculateNextHash(aggregateId, hash) .
then( () => store.dispatch({ type: SEND_COMMAND_UPDATE_HASH_SUCCESS, aggregateId, hash }) ) .
catch( (err) => store.dispatch({ type: SEND_COMMAND_UPDATE_HASH_FAILURE, aggregateId, hash }) ); break; } case SEND_COMMAND_UPDATE_HASH_FAILURE: { const { aggregateId } = action; const hash = tempHashes[aggregateId]; delete tempHashes[aggregateId]; store.dispatch({ type: OPTIMISTIC_ROLLBACK_HASH_UPDATED, aggregateId, hash }); break; } case HASH_UPDATED: { const { aggregateId } = action; const hash = tempHashes[aggregateId]; delete tempHashes[aggregateId]; store.dispatch({ type: OPTIMISTIC_ROLLBACK_HASH_UPDATED, aggregateId, hash }); break; } } next(action); } }
Хотя использовать их нужно разумно и с большой осторожностью.
В некоторых случаях они могут привести к потере данных и затруднить понимание пользовательского интерфейса.
Например, оптимистичный лайк под фото — это хорошо, а оптимистичная форма оплаты — плохо.
Так что не портите ситуацию.
Удачи! Теги: #react #cqrs #eventsourceing #optimistic #JavaScript #programming #node.js #react.js
-
Что Американцы Делают В Интернете?
19 Oct, 24 -
Как Вернуть Старый Лимит В 15 Гб На Onedrive
19 Oct, 24 -
Лицензирование Майкрософт
19 Oct, 24 -
Игра С Генетическими Алгоритмами
19 Oct, 24 -
Коллекция Ваших Работ Об Angular.js.
19 Oct, 24 -
Еще Один Первый Опыт Разработки Для Appstore
19 Oct, 24