Персистентная очередь на фронте
Что такое персистентная очередь? Это очередь, события в которой не потеряются в случае перезагрузки приложения.
Персистентная очередь во фронтенде (или в мобильном приложении) может быть использована только… пока фронтенд работает. Так ли уж она полезна?
Давайте разбираться.
Сперва разберёмся с вариантами применения просто очередей на фронте (всё сказанное о фронтенде можно так же смело применять и к мобильным приложениям).
Очереди на фронтенде могут быть полезны для:
- снижения общей пиковой на бакенд. Вместо того чтобы выполнять множество запросов к бакенду одновременно, выполняем все запросы фронта в обработчике очереди. Интерактивность приложения в таких случаях страдает обычно несильно, а вот пиковую нагрузку на бакенды можно довольно серьёзно размазать во времени. Метрика RPS в таком случае означает “пользователей (приложений) в секунду”.
- организации батчинга запросов. Пока выполняется очередной запрос к бакенду, фронт копит следующие запросы в очереди. Затем выполняет их одним пакетом (конечно, API бакенда должен такое уметь).
То есть, как видим, очередь на фронте - сама по себе весьма полезный инструмент. Если кто-то с этим паттерном не знаком, весьма рекомендую попробовать использовать при построении мобильных приложений/фронта.
А что же мы можем получить от персистентной очереди?
Конечно же, проблему обратной совместимости версий приложений! :) Каждое обновление приложения должно иметь в виду, что ему придётся, возможно, обработать задачи от очереди предыдущей версии. Впрочем, это не такая уж и большая проблема. Давайте рассматривать полезные применения.
Рассмотрим несколько примеров.
Лайки, пометки просмотренности итп
Пользователь просматривает ленту новостей, ленту в соцсети и т.п. В
процессе просмотра ставит лайки и дизлайки. Сохранять информацию о
принятых им решениях (таплы (id: решение)
) в персистентной очереди -
практически идеальное архитектурное решение:
- если в данный момент связь с интернетом есть, то информация о лайке уйдёт на сервер с минимальным лагом;
- если со связью проблема, то обработчик очереди выполнит задачу тогда, когда проблемы уйдут (через несколько секунд, минут). Возможно, даже в другой день.
Да, теоретически, информация о принятом пользователем решении может никогда не дойти до сервера, поэтому не стоит через такой инструмент проводить, скажем, финансовые транзакции пользователя.
Хотя… В некоторых случаях именно для финансов персистентная очередь тоже подойдёт.
Терминалы оплаты
Представьте себе терминал, принимающий денежные купюры, печатающий чек и делающий зачисление денег на счёт. Не банкомат, а, например, терминал а-ля Qiwi.
Если в данный момент времени связи с внешним миром у терминала нет, то он вполне может принять деньги у пользователя, выдать ему чек. Транзакция будет исполнена тогда, когда появится связь.
Если Вы посмотрите на своё мобильное приложение или сайт, то с большой степенью вероятности Вы найдёте места, где можно использовать персистентную или обычную очередь и улучшить дружелюбность приложения к пользователю, а где-то и сгладить пики нагрузки на бек.
Но во всех случаях, когда очереди применяются для аггрегации запросов, важно помнить об идемпотентности.
Идемпотентность
Википедия: Идемпоте́нтность – свойство объекта или операции при повторном применении операции к объекту давать тот же результат, что и при первом. Термин предложил американский математик Бенджамин Пирс в статьях 1870-х годов.
То есть, обработчик запросов фронтенда на беке должен иметь в виду, что связь между ним и приложением может быть нестабильна. А вследствие этого запросы могут повторяться.
Упреждающая простановка стейта
Поставив лайк, пользователь должен видеть результат сразу. Даже если этот лайк физически проставится позднее. Из этого следует, что действия пользователя, проводимые через очередь, в некоторых случаях должны менять локальный стейт немедленно.
Это может приводить к тому, что перезагрузка приложения с неразобранной персистентной очередью покажет пользователю, что действие ещё не выполнено.
С этим можно также бороться, добавляя персистентности в стейт. А можно… оставить, как есть. Для случаев, где это не выглядит большой проблемой.
Фреймворки
Для многих популярных фреймворков есть множество решений, реализующих персистентные и неперсистентные очереди в виде расширений фреймворков.
- например, для Redux есть offline-queue
- для Vue storage-based-queue
- и так далее.
Если для Вашего фреймворка не нашлось очереди, то её довольно просто написать самостоятельно.
Заключение
Описанный в статье довольно простой архитектурный приём позволит строить более дружелюбные к пользователю приложения/сайты. Множество мобильных приложений могли бы быть улучшены с помощью данной технологии и вместо показа “крутилок-лоадеров” или экранов с прогрессбарами реагировать на действия пользователя моментально. Но, увы, в жизни подобные подходы встречаются редко.
Возможно, эта статья поможет уменьшить количество секунд, которые пользователь проводит в ожидании перед Вашим приложением, и сэкономленное время он потратит на выставление хорошей оценки в сторе? Кто знает…