Ибо когда A посылает толстый поток данных на B, B - на C, C захлёбывается и просит B прикрутить краник - посылать сообщение об этом бессмысленно. Нормальным ходом оно дойдёт чёрт знает когда, а выбирать по маске с линейным перебором очереди - прямой способ убить всё вокруг нагрузкой.
Все альтернативные способы кривы. Прокси-процесс с flow control - лишняя нагрузка на пересылке. Самым разумным показалась эмуляция глобальной переменной через специальный процесс и gen_server:call() к нему на каждые 100-1000 обработанных сообщений. Главное, чтобы этот процесс не сдох сам от нагрузки.
Ну и как это называется? ;(
Все альтернативные способы кривы. Прокси-процесс с flow control - лишняя нагрузка на пересылке. Самым разумным показалась эмуляция глобальной переменной через специальный процесс и gen_server:call() к нему на каждые 100-1000 обработанных сообщений. Главное, чтобы этот процесс не сдох сам от нагрузки.
Ну и как это называется? ;(
no subject
Date: 2009-09-17 06:53 pm (UTC)no subject
Date: 2009-09-17 06:57 pm (UTC)Только с обратной связью будет та же самая проблема. Как только начинаешь думать чем это регулировать - ничего кроме отдельного процесса - хранителя флагов не получается.
Вообще мы уже доигрывались до двух миллионов сообщений в очереди, пока не решили, что в этом случае gen_server2 будет совершать торжественный суицид, ибо иначе ему всё равно жизни не будет. Вот с писателем базы проще - если он обнаруживает в очереди over 9000 (tm) сообщений, он их всех тупо сбрасывает не читая, а затем переписывает базу на диске с нуля из ets.
no subject
Date: 2009-09-17 07:05 pm (UTC)Нуачо. Квитирование с окном - классическая схема :)
> Только с обратной связью будет та же самая проблема
Я правильно понимаю, что проблема заключается в том, что сообщение от C будет отлеживаться в очереди B, которая забита сообщениями от A? Так может и A того, отфлоуконтролить?
А нельзя ли вообще какой state compression применить?
no subject
Date: 2009-09-17 07:23 pm (UTC)Так чтобы его отфлоуконтролить - снова "рекурсия см. рекурсия"
> А нельзя ли вообще какой state compression применить?
Этого не понял.
no subject
Date: 2009-09-17 07:56 pm (UTC)Ну, A-то события
* либо сам придумывает - тут все понятно,
* либо берет события из внешнего мира - тут все зависит от механизма общения с внешним миром: если там tcp, то опять же ясно, если там чего-то по своей природе нефлоконтролящееся, то накапливать/сбрасывать,
* либо получает сообщения от процесса Z - тут да, А должен флоуконтролить Z, а Z - Y, а бабка за дедку и так до самой репки, т.е. до источника событий.
> Этого не понял.
Я как-то хотел про это отдельный пост написать, но чего-то не собрался. Расскажу тогда здесь.
Я не знаю твоей ситуации, поэтому примеряй к своей задаче сам.
Многие приложения можно поделить на два куска: кусок, общающийся с внешним миром, и кусок делающий работу.
По отношению к событиям эти два куска часто работают очень по-разному.
Кусок, который говорит с внешним миром, заинтересован видеть все события, которые вокруг происходят: в этом куске живет протокольная машина, отрабатывающая эти события и меняющая свое состояние по этим событиям.
А куску, делающему работу, в целом по барабану события, как собственно события. Ему интересно состояние протокольной машины, каковое он обработает каким-то сложным образом.
Возьмем пример, который близок мне - протоколы маршрутизации. Какой-нибудь OSPF или IS-IS. Там это деление очень прозрачно. Есть протокольная машина (даже несколько), есть link-state database, которая пополняется этими машинами. А есть вычислитель маршрутов, засовыватель этих маршрутов в forwarding plane и прочая умная машинерия.
Обработка событий протокольной машиной здесь очень проста, а следовательно очень производительна. Всего-то делов - засунуть пришедший link-state pdu в нужное место LSDB. А вот думатели - они по сравнению с этим медленные, и с потоком событий могут просто не справиться. Строить к ним очереди из событий нельзя - очередь может вырастать непредсказуемо и разгребание ее может занять непредсказуемое время.
Ход здесь совершенно очевидный. Протокольная машина, получив событие из сети и изменив соответствующим образом состояние LSDB, _один_ раз уведомляет думатель. А у уж думатель, когда у него будет время, возьмет самое распоследнее состояние, сделает что надо, и скажет протокольной машине "дерни меня, если чо".
Т.е. неуправляемый поток событий внешнего мира преобразуется в очень даже управляемый и предсказуемый поток уведомлений (с подтверждением - т.е. по своей природе flow-controlled) плюс накопление состояния.
no subject
Date: 2009-09-18 05:31 am (UTC)Проблемы видятся следующие:
1. В такой постановке база (твоя LSDB) - разделённый ресурс на общей памяти или чём-то подобном, что невозможно при чистом обмене сообщениями.
2. Пока "думатель" думает, базу нельзя править напрямую. Модуль протокола должен или тормозить на локе, или сложить изменение в очередь и уйти. Получаем ещё худшую ситуацию в профиль.
Решением мог быть бы промежуточный агент, которому протокольные модули кидают изменения как сообщения, а он уже кормит LSDB и спокойно ждёт на локе. Осталось понять, что будет, если и его очередь переполнится.;)
no subject
Date: 2009-09-18 07:51 am (UTC)Угу. Я бы даже сказал, что это, простигосподи, design pattern.
> база - разделённый ресурс на общей памяти
...
> Решением мог быть бы промежуточный агент, которому протокольные модули кидают изменения как сообщения
Именно. Отдельный держатель базы. А чтоб его не зафлудить, он может флоуконтролить протокольную машину. И/или протокольный модуль может бэтчить апдейты.
> Пока "думатель" думает, базу нельзя править напрямую. Модуль протокола должен или тормозить на локе, или сложить изменение в очередь и уйти.
Можно лок, да. Можно snapshot копированием. А можно вспомнить, что у нас язык функциональный и на чистых структурах данных copy-on-write получается сам.
no subject
Date: 2009-09-18 06:04 pm (UTC)У кого получается, у кого нет. У Erlang'а такое copy-on-write работает только в пределах одного процесса. Между хипами процессов кросс-ссылок не может быть в принципе.
> Именно. Отдельный держатель базы. А чтоб его не зафлудить, он может флоуконтролить протокольную машину. И/или протокольный модуль может бэтчить апдейты.
Страшно звучит, но надо подумать.
no subject
Date: 2009-11-24 10:06 am (UTC)Правда, сырое оно ещё.
no subject
Date: 2009-11-24 10:30 am (UTC)no subject
Date: 2009-11-24 12:31 pm (UTC)Пока не хватает библиотек, переносимости и надёжности.
no subject
Date: 2010-05-25 06:33 pm (UTC)