LINUX.ORG.RU

Алгоритм отложенной подписки на событие

 , , ,


0

1

Подскажите паттерн/способ «отложенной подписки на событие».

Предположим есть событие 'sample_event'. И подписка на это событие, но факт подписки случается ПОСЛЕ ТОГО как событие было разослано всем тек. слушателям:

// эмиттер разослал событие текущим "слушателям"
emitter.emit('sample_event');

...
спустя минуту появляется новый "слушаетель" и хочет подписать на событие 'sample_event'

emitter.on( 'sample_event', some_function_reference );

Хочется, чтобы при таком раскладе данный «слушатель» ПОЛУЧИЛ реакцию на это событие, несмторя на то, что событие было разослано минуту назад.

Какие есть ли алгоритмы/паттерны/подходы для реализации такой хотелки?

Спасибо.

P.S. Не имеет значение на каком ЯП это реализовано.


А в чем смысл делать факт этой подписки отложенным явлением? Что должно произойти за время этого «откладывания». Не проще ли сделать подписку сразу, а потом просто отменить если есть какое-то условие?

anonymous ()
Ответ на: комментарий от anonymous

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

В общем-то типичный пример современной разработки, тянуть на каждый чих по «кафке».

anonymous ()

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

Nastishka ★★★★★ ()

Зависит от библиотеки, как правило, конфигурируется прямо в настройках паблишера. Есть паблишеры с поддержкой какой-то ограниченной очреди (N событий или M секунд); но тебе нужно помнить, что очереди нерезиновые и нужно думать о балансе хочу-могу. Если это браузер, лучше не тормозить, а если бекенд - смотри сам по ресурсам. Если нужно бесконечную очередь - посмотри в сторону персистентных систем (kafka/rabbitmq/что угодно).

cdshines ★★★★ ()

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

rukez ★★ ()

Закину свои три копейки.

Здесь у тебя либо непонимание того, чего ты по итогу хочешь от паттерна PUB/SUB, либо ты переусложняешь то, что ты должен реализовать.

Обычно, при использовании таких паттернов, все понимают, что только после момента подписки, сообщения начинают прилетать. Это может быть любой брокер сообщений, или фреймворк, который такой функционал предоставляет (0MQ, RabbitMQ, Kafka, любой MQTT брокер).

В случае, если тебе реально нужен такой функционал, то я бы на твоем месте раскурил Apache Kafka или RabbitMQ. Но я ни разу с такими настройками я там не сталкивался.

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

f77e ()

Ну проще говоря, нужная какая то память, хранящая уже отправленные события для таких вот «опоздавших». Тут надо понимать, что память эта не может быть бесконечной, т.е. неразумно сделать так, что опоздавший придёт за событиями через неделю и получит их, куча данных будет где то храниться. Нужно определиться со временем, на которое опоздавшему разрешается опоздать и все события, которые выходят за эти временные рамки - удалять. Где данные об этих событиях хранить - это уже на ваш выбор, главное чтобы хранилище могло бы выдать эти события начиная с какого то timestamp, который опоздавший должен передавать (либо брать его откуда то, зная когда опоздавший получал событие последний раз, на уровне источника событий, короче, решать это), если опоздавший пытается запросить события, которых уже нет, потому что поздно пришел, то возникнет проблема консистентности данных, ведь тогда ему будут отданы неполные данные, а только те что остались на момент его обращения, лучше таких опоздавших считать «невосстановимо опоздавшими» и просто подписывать их на последующие события. Как видишь, всё это выглядит как чахлый костыль и есть много мест где это может порушиться. Поэтому ЛУЧШЕ ТАК НЕ ДЕЛАЙ и пересмотри свою логику.

fstronin ()

это так-же называется, проблема доставки «оффлайн сообщений»

Механизм подписок, особенно когда подписчиков немало - неэффективен. Начинаются проблемы маршрутизации, фильтрации. Несмотря на явных подписчиков. (man gang of four observer pattern and related) Это так, небольшое лирическое отступление …

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

Мне кажется у Вас что-то неправильно спроектировано т.к. это в принципе не нормальная ситуация. Классическая модель сходного поведения - почта.

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

anonymous ()
Ответ на: комментарий от anonymous

Мне кажется у Вас что-то неправильно спроектировано т.к. это в принципе не нормальная ситуация. Классическая модель сходного поведения - почта.

гениально!

спасибо ТС-у за полезную тему

anonymous ()