Как стать автором
Обновить

Комментарии 27

Персистентная очередь во фронтенде (или в мобильном приложении) может быть использована только... пока фронтенд работает

Что значит 'Пока фронтенд работает'?

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

А если пользователь ошибся в данных? А если свет вырубят? Что за ужасное решение вообще?

выполняем все запросы фронта в обработчике очереди. Интерактивность приложения в таких случаях страдает обычно несильно

Насколько не сильно? Выглядит как раз таки как будто сильно может пострадать

организации батчинга запросов

Но зачем?

То есть, как видим, очередь на фронте - сама по себе весьма полезный инструмент

Вы этого не показали, я этого не увидел

А что же мы можем получить от персистентной очереди?

Конечно же, проблему обратной совместимости версий приложений

И ещё кучу проблем

На самом деле как-то особых проблем там нет.

Есть Kafka, Rabbit, MQ... Все это вполне себе персистентные очереди.

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

Внутри сервера, платформа на которой он работает, имеет такой системный объект как DataQueue - *DTAQ (есть еще MessageQueue - *MSGQ) - это тоже персистентные очереди. *DTAQ широко используется для распараллеливания обработки в качестве конвейера при построении батчмашин. Головное задание запускает несколько однотипных заданий-обработчиков, затем занимается выборкой данных для обработки, формированием "пакетов" и выкладыванием их на конвейер. Обработчики разбирают пакеты с конвейера и обрабатывают их. Скорость конвейера тут не является критичной (в достаточно широких пределах) т.к. в конечном итоге все упирается в скорость обработки. В отличии от сокетов и пайпов *dtaq мониторится - можно всегда узнать сколько там в данное время лежит пакетов, оценить скорость разбора (обработки), варьировать количество обработчиков, избегать переполнения очереди.

Так что персистентные очереди вполне себе мощный инструмент.

Есть Kafka, Rabbit, MQ

Вы сравниваете очередь в памяти браузера (или где она там) с Кафкой, серьёзно? Очереди - штука крутая в том числе за счёт гарантий которые они дают, а тут всё лежит в браузере и может быть сломано в любой момент, ну не знаю.
Ну и они дают задержку в отличие от прямого запроса, что на клиенте может быть более чем критично

Вообще-то "персистентная" подразумевает что она не исчезнет после закрытия или падения браузера (или что там у вас работает). Т.е. это явно не память браузера, а некое хранилище на диске.

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

При старте первым делом проверяем содержимое очередей.

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

Кстати, пакет тоже может иметь метку уровня критичности. От "попробовать доставить - не получится да и бог с ним" до "доставить любой ценой в любом случае". И это у нас тоже было реализовано.

Что значит 'Пока фронтенд работает'?

Если пользователь закроет окно браузера (или приложение), то то что осталось в персистентной очереди не будет обработано до тех пор пока браузер/приложение снова не запустят.

А если пользователь ошибся в данных? А если свет вырубят? Что за ужасное решение вообще?

Если пользователь ошибается, ему делают экраны "вы уверены?" итп.

Если Вы в банкомате переводили деньги и нечаянно перевели не ту сумму, что Вы можете сделать? Ничего. Звонить в банк и ждать решения вашего вопроса в течение нескольких дней.

Здесь отличий никаких

Насколько не сильно?

На доли секунд. Понятное дело, что если где-то это критично то решение не подойдёт. Важно никакое решение не воспринимать как "серебрянную пулю". Таковой не существует.

Если Вы в банкомате переводили деньги и нечаянно перевели не ту сумму, что Вы можете сделать? Ничего. Звонить в банк и ждать решения вашего вопроса в течение нескольких дней.

Здесь отличий никаких

Банк проверяет не только сумму, но и корректность счета, например, и много чего ещё. А у Вас терминал деньги забрал, но банку ничего не отправил и что мне делать? Искать производителей терминала? Это явно не 'здесь отличий никаких'.

Если пользователь закроет окно браузера (или приложение), то то что осталось в персистентной очереди не будет обработано до тех пор пока браузер/приложение снова не запустят.

При старте системы придётся учитывать, что возможно, есть очередь, которая уже, возможно, неактуальна и нужно разбираться в этом всём.

При старте системы придётся учитывать

я об этом написал в статье.

При использовании любой технологии что-то придётся учитывать. Это плата за использование технологии.

А у Вас терминал деньги забрал, но банку ничего не отправил и что мне делать?

то же что с банкоматом.

звонить в поддержку, посылать им фото чека (если он есть) или называть время, сумму и телефон, привязанный к счёту.

никакой разницы.

мы делали такую систему на приём выручки от таксистов.

Терминал собирал в себя до нескольких миллионов в день.

в терминале авторизационный кеш для таксистов (номера их телефонов).

таксист вносит сумму, указывая свой номер счета (с контрольной суммой внутри цифры) или номер телефона (проверяется по кешу).

затем вносит деньги. Транзакция попадает в персисиентную очередь браузера.

Есть связь или нет её совершенно не важно. Когда-либо связь восстановят и деньги доедут до счета :)

звонить в поддержку, посылать им фото чека (если он есть) или называть время, сумму и телефон, привязанный к счёту.

Я ж Вам привел пример когда терминал ничего не отправил, так как я ошибся в данных и в банк вообще ничего не ушло. Деньги остались в терминале. Это ещё лишняя прослойка какая то.

Я предпочитаю узнать о проблеме сети в терминале, а не получить ложное заявление и чек. Который, кстати, юридически вообще может быть выдан если операция не совершена? Время транзакции какое на чеке?

если вы ошиблись в данных, терминал Вам написал на экране "Ошибка", Вы исправили данные и все хорошо.

Банк проверяет не только сумму, но и корректность счета, например, и много чего ещё

Вы как то упускаете то, что я писал раньше

Терминал не может проверить всё.

я это уже комментировал.

терминал может проверить.

многие вещи очень легко проверяются оффлайн

вот например номер карты

1234 5678 9012 3456

Довольно просто проверяется на валидность

  • код оператора карты

  • контрольная сумма

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

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

Проблемы могут возникнуть у любого решения. Проблемы при любом уровне онлайновости.

Вы игнорируете ошибки, которые нельзя проверить офлайн

Вот я ввёл счёт (не номер карты) некорректно.

Терминал сказал, что всё ок.

Денег нет.

Банк ничего не знает о переводе, так как либо терминал ещё не отправил данные, либо не смог отправить т.к. банк отклонил

Мне теперь банк ничем не поможет, мне нужно в терминал, понимаете? Вероятно, в конкретный терминал в конкретном городе

Проблемы могут возникнуть у любого решения. Проблемы при любом уровне онлайновости.

Именно

И пользователь должен знать об этом, а Вы вводите в заблуждение

в номере счёта точно так же присутсвуют опорные цифры, как и в номере карты

Вы утверждаете, что офлайн можете проверить всё и банк никогда не откажет в операции по причине ошибки в данных, я понял

я утверждаю что серебряных пуль не бывает.

а если банк делает терминал для зачисления денег исключительно себе на счета, то да - не откажет.

обобщенному банкомату, конечно такое решение не подойдет.

Терминалу по оплате квартплаты, зачислению денег на телефон, автомату по сбору выручки итп - вполне

Поставив лайк, пользователь должен видеть результат сразу. Даже если этот лайк физически проставится позднее.

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

Хотя, надо признать, я не самый типичный пользователь соцсетей - большинству, наверно, предпочтительнее визуально быстрый сайт, но обманывающий их...

Ах, обмануть меня не трудно!..
Я сам обманываться рад!

Кстати именно у пикабу этой фичи нет. Кликаешь лайк - пикабу получает "сеть недоступна" и молча это проглатывает.

Была бы очередь - то воркер бы повторял отправку лайка до тех пор пока у него бы не получилось.

Была бы очередь - то воркер бы повторял отправку лайка до тех пор пока у него бы не получилось.

Моё имхо - в этом случае надо спиннер. А вот если быстрая одноразовая попытка, то вполне подойдёт упреждающий интерфейс с возможным откатом и сообщением об ошибке.

если со связью проблема, то обработчик очереди выполнит задачу тогда, когда проблемы уйдут (через несколько секунд, минут). Возможно, даже в другой день.

А если у меня что-то в реальном мире завязано на эту задачу? т.е., например я уверен что задача выполнилась успешно, и звоню кому-то что-то подтвердить, или делаю другую важную активность в реальном мире на основании того что я уверен что моя задача выполнена успешно. А она оказывается не выполнена, она оказывается в очереди!). Так значит об этом и надо честно сказать.

Поставив лайк, пользователь должен видеть результат сразу. Даже если этот лайк физически проставится позднее. 

я как пользователь предпочитаю увидеть правду, т.е. в данном случае что есть проблемы с сетью или с сервером.

Имхо, все эти offline-first, оптимистичный ux, pwa - зло, которое усложняет жизнь как разработчикам так и пользователям.
Нет интерента - так покажи ты правду, что мол "чувак, сейчас нет интернета, или решай сначала эту проблему, или займись пока чем-то другим полезным".

А если у меня что-то в реальном мире завязано на эту задачу?

то Вам эта технология не подойдёт

Термин вы откуда взяли? Вообще, персистентные очерди — это немного другое (особенно в контексте тега "алгоритмы").


У вас тут скорее просто сохраниение стейта в персистентном хранилище. То, что вы храните там очереди, ничем принципиально не отличается от хранения там каких-то пользовательских настроек.

Из мира БД.
in-memory vs персистентные

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

Цитата оттуда же

Уровни персистентности

Есть несколько уровней персистентности:

- частичная (англ. partial),

- полная (англ. full),

- конфлюэнтная (англ. confluent),

- функциональная (англ. functional).

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

Очередь с частичной персистентностью тоже может называться персистентной (почему нет?).

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

Но для того чтобы оставаться персистентной - ей не нужно хранить всё вечно. Достаточно реализовать частичную персистентность.

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

Нет. Сама очередь, как структура данных, не обладает какими-то свойстами. Она хранится в персистентном хранилище, да. Но это свойство хранилища (памяти), а не очереди.


В связи с этим предлагаю вам переименовать статью на "Очередь в персистентном хранилище на фронтенде".


Edit: вы же не будете называть таблицу, допустим, пользователей в персистентной DB — персистентным списком пользователей?

Но SQS, Rabbit итп очередями называют. Несмотря на то, что это не структуры данных.

вы же не будете называть таблицу, допустим, пользователей в персистентной DB — персистентным списком пользователей?

Почему нет?

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

Да, возможно поддерживающий частичную, а не полную персистентность. Но именно так.

Но SQS, Rabbit итп очередями называют.

Поскольку эти продукты реализуют именно очередь. В них невозможно/сложно хранить что-то другое.


Почему нет?

Потому что сам список — никакой не персистентный, а просто список?


Да, возможно поддерживающий частичную, а не полную персистентность. Но именно так.

Я же не придераюсь к частичной или полной персистентности. Просто термин "персистентная очередь" уже занят и он как раз про свойство очереди. А у вас свойство хранилища, в которое очередь засунута. Но сама очередь от этого не становится какой-то другой.

Поскольку эти продукты реализуют именно очередь. В них невозможно/сложно хранить что-то другое.

Чем SQS, реализующая "именно очередь", отличается от класса в JS, реализующего "именно очередь"?

Наличием урлов конфигурации?

Потому что сам список — никакой не персистентный, а просто список?

  • Список сохраняется в независимой (от приложения) памяти? Да

  • Список переживает перезапуск приложения? Да

Почему список нельзя назвать персистентным? Частичная персистентность? Да. А полной в природе не встречается, ибо полная персистентность - понятие идеализированное. Рано или поздно хранилище будет удалено и данные из него потеряются. С этого момента нельзя будет запросить данные.

Я же не придераюсь к частичной или полной персистентности. Просто термин "персистентная очередь" уже занят и он как раз про свойство очереди.

Я бы не рассматривал данный источник как место где застолбили название для строго одного явления.

Мало того понятия "синонимы", "одни и те же термины на разных уровнях" никто не отменял (Подробнее см. в книге Богданова "Тектология или всеобщая организационная наука").

Когда мы говорим о структурах данных - персистентная очередь это одно.

Когда мы говорим о коде или сервисе, реализующем очередь , то персистентная очередь - это другое.

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

В данной статье речь идёт о технологии, как паттерне построения фронтендов/мобильных приложений. "Хозяйке на заметку": Применили просто очередь - смогли не делать параллельные запросы на сервер. Пиковая нагрузка на нём упала.
Применили очередь с памятью на диске - смогли сразу показать пользователю некоторые вещи как "уже сделано", хотя оно ещё может быт и не сделано.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.