netch80: (Default)
[personal profile] netch80
Ибо когда A посылает толстый поток данных на B, B - на C, C захлёбывается и просит B прикрутить краник - посылать сообщение об этом бессмысленно. Нормальным ходом оно дойдёт чёрт знает когда, а выбирать по маске с линейным перебором очереди - прямой способ убить всё вокруг нагрузкой.

Все альтернативные способы кривы. Прокси-процесс с flow control - лишняя нагрузка на пересылке. Самым разумным показалась эмуляция глобальной переменной через специальный процесс и gen_server:call() к нему на каждые 100-1000 обработанных сообщений. Главное, чтобы этот процесс не сдох сам от нагрузки.

Ну и как это называется? ;(

Date: 2009-09-17 06:53 pm (UTC)
From: [identity profile] dbg.livejournal.com
Реализовать flow control а-ля active_once между C и B? Или все распределенное и времени на round-trip жалко?

Date: 2009-09-17 06:57 pm (UTC)
From: [identity profile] netch80.livejournal.com
Конечно, времени не хватит. active_once на наших потоках точно сдохнет. Тут что-то вроде active_1000 бы.;)
Только с обратной связью будет та же самая проблема. Как только начинаешь думать чем это регулировать - ничего кроме отдельного процесса - хранителя флагов не получается.

Вообще мы уже доигрывались до двух миллионов сообщений в очереди, пока не решили, что в этом случае gen_server2 будет совершать торжественный суицид, ибо иначе ему всё равно жизни не будет. Вот с писателем базы проще - если он обнаруживает в очереди over 9000 (tm) сообщений, он их всех тупо сбрасывает не читая, а затем переписывает базу на диске с нуля из ets.

Date: 2009-09-17 07:05 pm (UTC)
From: [identity profile] dbg.livejournal.com
> Тут что-то вроде active_1000 бы.;)

Нуачо. Квитирование с окном - классическая схема :)

> Только с обратной связью будет та же самая проблема

Я правильно понимаю, что проблема заключается в том, что сообщение от C будет отлеживаться в очереди B, которая забита сообщениями от A? Так может и A того, отфлоуконтролить?

А нельзя ли вообще какой state compression применить?

Date: 2009-09-17 07:23 pm (UTC)
From: [identity profile] netch80.livejournal.com
> Я правильно понимаю, что проблема заключается в том, что сообщение от C будет отлеживаться в очереди B, которая забита сообщениями от A? Так может и A того, отфлоуконтролить?

Так чтобы его отфлоуконтролить - снова "рекурсия см. рекурсия"

> А нельзя ли вообще какой state compression применить?

Этого не понял.

Date: 2009-09-17 07:56 pm (UTC)
From: [identity profile] dbg.livejournal.com
> Так чтобы его отфлоуконтролить - снова "рекурсия см. рекурсия"

Ну, A-то события
* либо сам придумывает - тут все понятно,
* либо берет события из внешнего мира - тут все зависит от механизма общения с внешним миром: если там tcp, то опять же ясно, если там чего-то по своей природе нефлоконтролящееся, то накапливать/сбрасывать,
* либо получает сообщения от процесса Z - тут да, А должен флоуконтролить Z, а Z - Y, а бабка за дедку и так до самой репки, т.е. до источника событий.

> Этого не понял.

Я как-то хотел про это отдельный пост написать, но чего-то не собрался. Расскажу тогда здесь.

Я не знаю твоей ситуации, поэтому примеряй к своей задаче сам.

Многие приложения можно поделить на два куска: кусок, общающийся с внешним миром, и кусок делающий работу.

По отношению к событиям эти два куска часто работают очень по-разному.

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

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

Возьмем пример, который близок мне - протоколы маршрутизации. Какой-нибудь OSPF или IS-IS. Там это деление очень прозрачно. Есть протокольная машина (даже несколько), есть link-state database, которая пополняется этими машинами. А есть вычислитель маршрутов, засовыватель этих маршрутов в forwarding plane и прочая умная машинерия.

Обработка событий протокольной машиной здесь очень проста, а следовательно очень производительна. Всего-то делов - засунуть пришедший link-state pdu в нужное место LSDB. А вот думатели - они по сравнению с этим медленные, и с потоком событий могут просто не справиться. Строить к ним очереди из событий нельзя - очередь может вырастать непредсказуемо и разгребание ее может занять непредсказуемое время.

Ход здесь совершенно очевидный. Протокольная машина, получив событие из сети и изменив соответствующим образом состояние LSDB, _один_ раз уведомляет думатель. А у уж думатель, когда у него будет время, возьмет самое распоследнее состояние, сделает что надо, и скажет протокольной машине "дерни меня, если чо".

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

Date: 2009-09-18 05:31 am (UTC)
From: [identity profile] netch80.livejournal.com
Идея понятная и известная. Например, ещё в ранних Unix обработчик аппаратного прерывания минимизировался до "поставить флажок, дёрнуть низ и выйти", а всю сложную обработку на много таких "рывков" делали кодом в более спокойном состоянии. Или у меня тут же - если писатель диска явно не успевает писать изменения, он плюёт на это и записывает базу с нуля. В самом тяжёлом случае он просто будет её систематически писать, и это будет всё равно достаточно адекватно.
Проблемы видятся следующие:
1. В такой постановке база (твоя LSDB) - разделённый ресурс на общей памяти или чём-то подобном, что невозможно при чистом обмене сообщениями.
2. Пока "думатель" думает, базу нельзя править напрямую. Модуль протокола должен или тормозить на локе, или сложить изменение в очередь и уйти. Получаем ещё худшую ситуацию в профиль.
Решением мог быть бы промежуточный агент, которому протокольные модули кидают изменения как сообщения, а он уже кормит LSDB и спокойно ждёт на локе. Осталось понять, что будет, если и его очередь переполнится.;)

Date: 2009-09-18 07:51 am (UTC)
From: [identity profile] dbg.livejournal.com
> Идея понятная и известная.

Угу. Я бы даже сказал, что это, простигосподи, design pattern.

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

Именно. Отдельный держатель базы. А чтоб его не зафлудить, он может флоуконтролить протокольную машину. И/или протокольный модуль может бэтчить апдейты.

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

Можно лок, да. Можно snapshot копированием. А можно вспомнить, что у нас язык функциональный и на чистых структурах данных copy-on-write получается сам.

Date: 2009-09-18 06:04 pm (UTC)
From: [identity profile] netch80.livejournal.com
> Можно лок, да. Можно snapshot копированием. А можно вспомнить, что у нас язык функциональный и на чистых структурах данных copy-on-write получается сам.

У кого получается, у кого нет. У Erlang'а такое copy-on-write работает только в пределах одного процесса. Между хипами процессов кросс-ссылок не может быть в принципе.

> Именно. Отдельный держатель базы. А чтоб его не зафлудить, он может флоуконтролить протокольную машину. И/или протокольный модуль может бэтчить апдейты.

Страшно звучит, но надо подумать.

Date: 2009-11-24 10:06 am (UTC)
ext_605364: geg MOPO4 (Default)
From: [identity profile] gegmopo4.livejournal.com
А Go интересовались? Там как раз множество каналов-очередей (и сами они могут передаваться).

Правда, сырое оно ещё.

Date: 2009-11-24 10:30 am (UTC)
From: [identity profile] netch80.livejournal.com
Интересовался. Хилый закос под Алгол-68 с перенятием худших черт Си. Пока что несъедобно.

Date: 2009-11-24 12:31 pm (UTC)
ext_605364: geg MOPO4 (Default)
From: [identity profile] gegmopo4.livejournal.com
Да, «подправленный» Си. На мой взгляд недостаточно революционный за такую цену и слишком много сахара. Но если станет достаточно популярным, будет не хуже других мейнстримовых языков. Каналы, например, я хочу во всех языках. С встроенным select.

Пока не хватает библиотек, переносимости и надёжности.

Date: 2010-05-25 06:33 pm (UTC)
From: [identity profile] dadv.livejournal.com
Цискины low-latency-queues? Очередь для контрольных out-of-bound сообщений резко ограниченной длины и абсолютного приоритета обработки...
Page generated Jan. 2nd, 2026 02:33 pm
Powered by Dreamwidth Studios