SObjectizer: I Love This Game!
От: Евгений Охотников Беларусь http://eao197.blogspot.com
Дата: 30.12.05 17:19
Оценка: 480 (12) -1
Статья:
SObjectizer: I Love This Game!
Автор(ы): Евгений Охотников
Дата: 31.03.2006
Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


Авторы:
Евгений Охотников

Аннотация:
Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: Аноним  
Дата: 02.01.06 23:29
Оценка: :))) :))) :))
Ребята не имею ничего личного к автору, при общении с ним убеждался в его проффесионализме, но увидев статью не смог сдержаться. Софт, написанный на этом движке, (работал с ним лично) это один единый гармонично работающий глюк. Не поддающийся логичному лечению и благодаря вашей работе с годами он только совершенствуется, становясь все более непредсказыемым. Хотя по мне — ничего личного к вам не имею. Но тем не менее могу сказать только одно — ваш софт, написанный на этой платформе это и есть одна единая проблема.
Мультизадачность требует более глубокого анализа и серьезного подхода. Очень много недочетов, всплывающих впоследствии, что серьезно отражается на работе написанных на этой платформе программ. Можно также отметить, что используются слишком громоздкие конструкции для генерации системы имен и классов, что больше характерезует такую работу как диссертационную, а не как коммерческий проект.
Вывод можно сделать только один — ваша работа при дальнейшей разработке может вылиться в докторскую диссертацию.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.01.06 07:23
Оценка:
Здравствуйте, Аноним

Жаль, что общение происходит на анонимном уровне. У меня почта есть, я бы с удовольствием выслушал конкретную критику в адрес SObjectizer-а и разработанных на его основе продуктов.

А>Софт, написанный на этом движке, (работал с ним лично) это один единый гармонично работающий глюк.


Какой именно софт?

A>Но тем не менее могу сказать только одно — ваш софт, написанный на этой платформе это и есть одна единая проблема.


Имхо, такие слова можно отнести к очень большому количеству софта, написанного на "более патентованных" технологиях (CORBA, J2EE, COM).

А>Очень много недочетов, всплывающих впоследствии, что серьезно отражается на работе написанных на этой платформе программ.


Про наличие недочетов я и сам знаю. Но с какими именно довелось столкнуться именно вам?
Ваши слова могли бы существенно поднять приоритет работ над этими проблемами.

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


Например?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: SObjectizer: I Love This Game!
От: VladD2 Российская Империя www.nemerle.org
Дата: 05.01.06 18:39
Оценка: 1 (1) +1 -3 :))) :)))
Здравствуйте, eao197, Вы писали:

E>Ваши слова могли бы существенно поднять приоритет работ над этими проблемами.


Сразу оговорюсь... аноним — это не я.

Я думаю, самая большая проблема этого продуката — С++.
Причем не то даже плохо, что сам продукт на плюсах написан. А то что прикладные решения прийдется писать на них. Все же не серьзно рассчитвать, что на серевере будет жить море кода с ручным управлением памяти написанного на небезопасном языки и при этом не будет моря глюков.

Учитесь у МС. У них тоже многие серверы на плюсах написаны, но вот прикладникам в основном предлагается развивать их уже в безопасном режиме. И это правильно.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.01.06 07:51
Оценка: 1 (1) +1
Здравствуйте, VladD2, Вы писали:

VD>Сразу оговорюсь... аноним — это не я.


Я и не сомневался.

VD>Я думаю, самая большая проблема этого продуката — С++.


...Э ... у... ну... так уж получилось. Исторически. И не факт, что если бы в 2001-2002 годах SObjectizer был бы реализован на чем-нибудь управляемом (ближе всего в это время была Java), то SObjectizer получился бы настолько быстрым, каким он является сейчас.

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


Мне кажется, что существующее положение вещей данный довод опровергает. Существует масса кода на C/C++, которые работают в режиме 24x7, не глючат и не падают. Существует не мало кода на Java, который должен был бы работать в режиме 24x7, но падает.

Разговоры о том, что на C++ нельзя писать надежные программы -- это от лукавого. Очень похожи на разговоры о том, что на динамических языках нельзя писать надежные программы. И то и другое не верно. Скорее C++ не облегчает написание надежных программ. Поэтому первый же дятел-разработчик легко вызывает крах большой системы.

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

Меня же больше напрягает в C++ отсутствие настолько продвинутых фреймворков, как JDK или .NET. Поэтому даже выбор библиотеки для работы с HTTP-транспортом или с РСУБД выливается в совершенно не нужную головную боль. И затем оказывается, что в реальной системе от SObjectizer-а всего 20% кода, а все остальное -- это работа с какими-нибудь libcurl, libiconv, otl, libxml2 и пр.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game!
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.01.06 18:51
Оценка: -4 :)
Здравствуйте, eao197, Вы писали:

E>...Э ... у... ну... так уж получилось. Исторически. И не факт, что если бы в 2001-2002 годах SObjectizer был бы реализован на чем-нибудь управляемом (ближе всего в это время была Java), то SObjectizer получился бы настолько быстрым, каким он является сейчас.


1. Уверен, что скорость продукта в большей степени зависит от качества кода и алгоритмов. Ява даст оверхэд в среднем процентов в 20-70. Это не те цифры.
2. Кто сказал, что скорости не достаточно, а надежности избыточно? Вот аноним намекает на то, что как раз недостаточно надежности.
3. Перефразирую себя. Написать один сервер окуратно на С++ задача решаемая. Если потратить много денег/времени на тестирование, то он без сомнения будет работать. Но вот писать прикладной код на С++ — это маразм. На это способны еденицы. И если ты хочешь чтобы твой сервер был востребован, то его АПИ должен быть ориентирован на безопасный язык!

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


E>Мне кажется, что существующее положение вещей данный довод опровергает.


Это как? У вас море пользователей пишущих прикладные системы с использванием вашего сервера? Или аноним тут не про баги говорил (может это конкрент-провокатор?)?

E> Существует масса кода на C/C++, которые работают в режиме 24x7, не глючат и не падают. Существует не мало кода на Java, который должен был бы работать в режиме 24x7, но падает.


Ой, позволь не поверить. Думаю что работающего прикладного серверного кода написанного на Яве куда больеше чем написанного на С++.

E>Разговоры о том, что на C++ нельзя писать надежные программы -- это от лукавого.


Гарантированно надежные — это факт. Ну, да я не о том. Я о общей надежности решений. Если бы твои слова были бы правдой, то веб-приложения писались бы на С++, а Ява никогда не заняла бы такой огромный рынок.

E> Очень похожи на разговоры о том, что на динамических языках нельзя писать надежные программы.


Что считать динамическими? На динамически типизированных? Все завист от сложности системы. Монолитные огромные наврено сложно писать. А нечто вроде веб-приложений можно. Вот только при этом языка должен быть безопасным. Большинство динамически типизированных языко этому требованию удовлетворяют. А С++ — нет. Потому он и не пригоден для разработки прикладного серверного софта. То жест потенциально конечно и на ассемблере можно написать код без ошибок. Но чем больше объем системы, чем больше и разношерстнее команда разрботчиков, чем меньше сроки, тем меньше вероятность получения надежного продукта. Причем в отличии от типобезопасных языков не факт, что удастся за счет одного-двух талатнливых программистов быстро исправлять глуюки.

E> И то и другое не верно. Скорее C++ не облегчает написание надежных программ. Поэтому первый же дятел-разработчик легко вызывает крах большой системы.


Знашь, я вот сомтрю вокур и удивляюсь. С кем не заговоришь так он не дятел. А вокруг одни дятлы, дятлы, дятлы...
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.01.06 22:23
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>1. Уверен, что скорость продукта в большей степени зависит от качества кода и алгоритмов. Ява даст оверхэд в среднем процентов в 20-70. Это не те цифры.


70% это очень приличная величина. Даже 50% это уже слишком много.

VD>2. Кто сказал, что скорости не достаточно, а надежности избыточно? Вот аноним намекает на то, что как раз недостаточно надежности.


С анонимными утверждениями всегда трудно спорить.

VD>3. Перефразирую себя. Написать один сервер окуратно на С++ задача решаемая. Если потратить много денег/времени на тестирование, то он без сомнения будет работать. Но вот писать прикладной код на С++ — это маразм. На это способны еденицы. И если ты хочешь чтобы твой сервер был востребован, то его АПИ должен быть ориентирован на безопасный язык!


Если бы это был сервер... Это же не сервер, а встраиваемая в процесс библиотека. Для C++ она на C++. Для управляемых языков, вполне возможно, нужно будет делать полностью управляемый вариант.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: SObjectizer: I Love This Game!
От: Аноним  
Дата: 08.01.06 18:28
Оценка: -1
VD>>3. Перефразирую себя. Написать один сервер окуратно на С++ задача решаемая. Если потратить много денег/времени на тестирование, то он без сомнения будет работать. Но вот писать прикладной код на С++ — это маразм. На это способны еденицы. И если ты хочешь чтобы твой сервер был востребован, то его АПИ должен быть ориентирован на безопасный язык!

E>Если бы это был сервер... Это же не сервер, а встраиваемая в процесс библиотека. Для C++ она на C++. Для управляемых языков, вполне возможно, нужно будет делать полностью управляемый вариант.


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

Сказал бы просто народ не портите мне получение степени и все бы тебе на ура сказали, давай поможем. Но парить всем мозги и отнекиваться от очевидного факта не вижу смысла (все тот же аноним)
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.01.06 18:55
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добавлю ложку дегтя. Встраиваемая библиотека, которая подтяоивает с собой еще пару десятков библиотек, что в общем-то не добавляет красоты решения.


Последняя стабильная версия SObjectizer тянет за собой 6 дополнительных библиотек. Общий объем SObjectizer-а вместе с библиотеками составляет ~110 тысяч строк (включая примеры и тесты). Текущая не стабильная версия, которая создается на основе ACE, использует 7 дополнительных библиотек (с учетом ACE). Все это идет в одном наборе и не требует автономной инсталляции или настройки (посмотреть, как это выглядит, можно на примере ObjESSty, кстати, практически все эти библиотеки используются и самой ObjESSty).

А>Сказал бы просто народ не портите мне получение степени и все бы тебе на ура сказали, давай поможем.


Степень я хотел получить с объектной СУБД (предтечей ObjESSty). SObjectizer никогда не имел отношения ни к науке, ни к моим амбициям в области научных или околонаучных степеней. Более того, мой личный вклад в разработку SObjectizer по сравнению с вкладом, например, Аркадия Косарева, Андрея Лабыча и Василия Гайдукова, настолько мал, что при всем желании я не смог бы выдавать SObjectizer за свое достижение.

A>Но парить всем мозги и отнекиваться от очевидного факта не вижу смысла (все тот же аноним)


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: SObjectizer: I Love This Game!
От: Dj.ValDen Украина http://ua.linkedin.com/in/dvalchuk
Дата: 08.01.06 20:01
Оценка: 13 (3) +4 -3 :))
E>Здравствуйте, VladD2, Вы писали:

Не ну не наглость, а?
Если вы не видели ни разу стабильных проектов на С++ то кто вам доктор???
Если там и есть баги — так де их нет?
Это нормальный процесс написания софта.

Да у нас при ошибке с памятью крешится апликуха.
Минус? С одной стороны да — с другой плюс — сразу видно багу.
У вас же программеры вымаливают у начальства ещё и ещё мощнее тачки.
Плохие программеры?
Ну дык сами выше говорили — сплошь и рядом ........

И кто вам сказал, что 2 хороших программиста не стабилизируют аппликуху на с++? Не избавят её от мемори ликов и тд и тп детских болезней?
Зачем такое говорить?

на плюсы уже 20 лет гонят — а они живут — и БУДУТ ЖИТЬ И РАЗВИВАТЬСЯ!

У вас одни детские болезни — у нас другие — так что не равняйте божий дар с яичницой.

Пишите на своих управляемых платформах "мега сервера" и не морочте людям голову.

Человек выложил свой труд — им с++ не понравился. Может в той работе главный аспект не надёжность и совсем не коммерческое использование.
Это что сказать англичанину — "Вы проиграли в футбол потому, что у вас правостороннее движение."
С уважением Denys Valchuk

IMHO чем больше мнений тем оптимальней выбор варианта... :)
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.01.06 22:07
Оценка: 1 (1)
Здравствуйте, Dj.ValDen, Вы писали:

<...со скипанным согласен...>

DV>Человек выложил свой труд — им с++ не понравился.


Влад прав вот в чем: то, что проект на C++, в данной конкретной ситуации сильно усложняет:
— интеграцию его с приложениями на других языках. Просто потому, что для элементарных вещей, вроде, XML, HTTP, SOAP, XML-RPC приходится искать библиотеки, качество которых может оставлять много лучшего;
— разработку современных приложений с логированием, доступом к БД, работой с XML, поддержкой SOAP, unit-тестингом и пр. Опять же по причине того, что все эти инструменты не объеденены в один согласованный SDK.

Тем не менее, я не согласен, что сейчас все нужно делать на управляемых языках. Были, есть и будут области, где C++ еще долго будет вне конкуренции (просто по эффективности, предсказуемости и низкой ресурсоемкости).

DV>Может в той работе главный аспект не надёжность и совсем не коммерческое использование.


По поводу надежности: нашелся один аноним, который бросил пару бездоказательных фраз. Не называя ни названий конкретных продуктов, ни увиденных им багов/проблем. И его мнение априори начинает считаться объективным и адекватным. Между тем, компания, которая занимается разработкой и использованием SObjectizer-а, продает свои решения и использует их каждый день. Созданные на SObjectizer системы работают прямо сейчас. Баги есть, как же без них, но крайне редко именно SObjectizer тому причина. Меня бы давно выгнали с работы, если бы мы на SObjectizer-е делали ненадежное ПО.

По поводу коммерции: я не маркетолог и не продавец. Моя цель -- привлечь внимание к SObjectizer. Имхо, нельзя применить только то, чего нет. И если новые применения для SObjectizer-а найдуться, то с коммерцией мы там как-нибудь разберемся.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: SObjectizer: I Love This Game!
От: Dj.ValDen Украина http://ua.linkedin.com/in/dvalchuk
Дата: 08.01.06 23:08
Оценка:
E>- разработку современных приложений с логированием, доступом к БД, работой с XML, поддержкой SOAP, unit-тестингом и пр. Опять же по причине того, что все эти инструменты не объеденены в один согласованный SDK.

это у вас не объединены

E>Тем не менее, я не согласен, что сейчас все нужно делать на управляемых языках. Были, есть и будут области, где C++ еще долго будет вне конкуренции (просто по эффективности, предсказуемости и низкой ресурсоемкости).


SObjectizer.

А где об этом можно больше узнать кроме как в номере журнала?
С уважением Denys Valchuk

IMHO чем больше мнений тем оптимальней выбор варианта... :)
Re[10]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.01.06 05:52
Оценка:
Здравствуйте, Dj.ValDen, Вы писали:

E>>- разработку современных приложений с логированием, доступом к БД, работой с XML, поддержкой SOAP, unit-тестингом и пр. Опять же по причине того, что все эти инструменты не объеденены в один согласованный SDK.


DV>это у вас не объединены


А у вас объеденены?
Как, если не секрет?

Я знаю, что, например, Qt все это в одном флаконе предоставляет.

DV> SObjectizer.


DV>А где об этом можно больше узнать кроме как в номере журнала?


Самая полная информация о SObjectizer в виде небольшого учебника по программированию в SObjectizer собрана здесь (~1.2Mb).


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: SObjectizer: I Love This Game!
От: Dj.ValDen Украина http://ua.linkedin.com/in/dvalchuk
Дата: 09.01.06 11:05
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, Dj.ValDen, Вы писали:


E>>>- разработку современных приложений с логированием, доступом к БД, работой с XML, поддержкой SOAP, unit-тестингом и пр. Опять же по причине того, что все эти инструменты не объеденены в один согласованный SDK.


DV>>это у вас не объединены


E>А у вас объеденены?

E>Как, если не секрет?

E>Я знаю, что, например, Qt все это в одном флаконе предоставляет.


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

IMHO чем больше мнений тем оптимальней выбор варианта... :)
Re[4]: SObjectizer: I Love This Game!
От: GU Glez  
Дата: 09.01.06 20:26
Оценка: 9 (1)
Здравствуйте, VladD2, Вы писали:
VD>Я думаю, самая большая проблема этого продуката — С++.
Влад, Вы опять о своем, наболевшем?

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

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

VD>Учитесь у МС. У них тоже многие серверы на плюсах написаны, но вот прикладникам в основном предлагается развивать их уже в безопасном режиме. И это правильно.


ЗЫ. Евгений, в чем Влад действительно прав, так это во вопросе интеграции серверного и прикладного софта — должна быть ифраструктура. Без этого никуда, поэтому сложно представить быструю разработку качественного софта построенного на основе SObjectizer (вот тут .NET впереди планеты всей. каким стал в свое время Visual Basic с ActiveX-ом).
С уважением,
GU Glez [Джи Ю Глиз]
Re[5]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.01.06 08:09
Оценка: 7 (2)
Здравствуйте, GU Glez, Вы писали:

GG>ЗЫ. Евгений, в чем Влад действительно прав, так это во вопросе интеграции серверного и прикладного софта — должна быть ифраструктура.


С этим я как раз согласен. См. здесь
Автор: eao197
Дата: 09.01.06
.

GG>Без этого никуда, поэтому сложно представить быструю разработку качественного софта построенного на основе SObjectizer (вот тут .NET впереди планеты всей. каким стал в свое время Visual Basic с ActiveX-ом).


А можно узнать твой способ деления софта на серверный и прикладной?

Я это к тому, что если пытаться на SObjectizer делать формы доступа к БД, то это совершенно бесполезное занятие. В SObjectizer вообще нет никаких вспомогательных средств для этого. Но вот если представить себе приложение, которое содержит графический GUI и должно управлять какой-нибудь железякой или снимать измерения с этой железяки. GUI часть можно писать на Qt, wxWidgets или MFC. GUI будет работать на основной нити приложения. Часть для общения с железом будет работать на другой нити (нитях). Как-то нужно организовать взаимодействия между этими нитями и объектами, которые в них живут. Тут как раз может помочь SObjectizer. Для этого в виде агентов оформляются объекты для взаимодействия с железом. Так же в виде агентов могут быть оформлены некоторые части GUI (окна). Когда от пользователя через GUI поступает команда на железяку всего лишь нужно переслать сообщение соответствующему железячному агенту. Точно так же, если железячный агент обнаруживает изменения в состоянии оборудования, он отсылает сообщение агенту в GUI и агент получатель отображает это изменение в виде какого-то индикатора.

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

Но в многопоточных приложениях, имхо, такая помощь разработчику со стороны SObjectizer-а означает довольно многое. Предположим, что создается фильтр какого-нибудь телекомуникационного протокола. Выделяется транспортый объект точки входа в фильтр. Он разбирает входящий трафик и преобразует его в прикладные сообщения. Эти сообщения рассылаются в глубь приложения с тем, чтобы кто-то их дальше обработал. При этом транспортый агент так же рассылает сообщения о происходящих событиях в систему логирования. Так же транспортый агент обновляет у себя статистическую/мониторинговую информацию (и эти изменения так же в виде сообщений уходят в подсистему мониторинга). Далее прикладные сообщения поступают агенту-фильтру, преобразуются и отсылаются другому транспортому агенту. Параллельно с этим подсистема логирования и подсистема мониторинга может отсылать сообщения о происходящих событиях на удаленную машину к службе техобслуживания. При этом всем программисту не нужно заботится об очередях сообщений, о блокировках (mutex-ах) и уведомлениях (event-ах или condition variable), о пулах потоков и пр.

Вот это роль SObjectizer как до сих пор видел ее я. То, что SObjectizer написан на C++ -- это следствие истории его развития ("Все мы жертвы цепи нелепых случайностей" (C) К.Вонегут). Если в SObjectizer-е будет заинтересованность, то он может быть реализован и на других языках (не сразу, конечно). Мне хотелось бы понять, будет ли в этом потребность (т.е. заинтересованность читателей журнала и форума) и, если будет, то к какому языку прежде всего нужно будет присмотреться.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: SObjectizer: I Love This Game!
От: GU Glez  
Дата: 10.01.06 10:53
Оценка:
Здравствуйте, eao197, Вы писали:
E>А можно узнать твой способ деления софта на серверный и прикладной?
Все это конечно, не более чем вопрос терминологии. Понятно, что для GUI SObjectizer — есть "не то". Вышла ситуация "кто в лес, кто по дрова". Просто я (за всех других учасников форума сказать не могу), но не Вы, как один из разработчиков) хуже представляю как и где нужно использовать SObjectizer. Видимо читал не внимательно . Одно дело "шампунь и кондиционер в одном флаконе", и другое сложное серверное приложение с GUI-интерфейсом. ИМХО, последнее надо бы разделять, чтобы в последствии слить воедино, но ввиде уже двух независимых программ (насколько это возможно) — одно на C++ (SObjectizer), другая на GC-языке. Вот такое мое видение. Т.к. сервер. программы все время делал один, то намучившись понял, что такой подход является более правильным (читай устойчивым), чем тот, который предлагает "держать все яйца в одной корзине".

Это все касаемо серверно()-клиентских приложений. Если рассматривать программу (любую), построенную как [измерительная часть] + [GUI], тогда да. О чем собственно Вы и пишите:
1.

SObjectizer не является жестким каркасом потому, что он не требует, чтобы все приложение было «написано на агентах». Напротив, SObjectizer позволяет реализовать лишь часть объектов приложения в виде агентов. Так, с помощью SObjectizer создавались CGI-модули, в которых SObjectizer запускался только для выполнения одного действия — запроса данных от другого приложения. После выполнения этого запроса SObjectizer останавливался, а CGI-модуль продолжал свою работу. При этом объем кода CGI, который работал с SObjectizer, составлял всего несколько процентов от общего объема кода модуля.

2.

Также SObjectizer не накладывает органичений на способы интерактивного взаимодействия с пользователем. С помощью SObjectizer можно создавать «черные ящики», работающие вообще без какого-либо диалога с пользователем. Но можно создавать и полноценные GUI-приложения с применением готовых оконных библиотек, таких как MFC, ATL, WTL, Qt, wxWindows и др.


ЗЫ. Статью, к сожалению, я не читал (еще журнал не дошел), но pdf-ник просмотрел. Возможно отсюда и мое недопонимание сути SObjectizer.
С уважением,
GU Glez [Джи Ю Глиз]
Re[10]: SObjectizer: I Love This Game!
От: AVC Россия  
Дата: 10.01.06 11:00
Оценка: 33 (4)
Здравствуйте, Dj.ValDen, Вы писали:

DV> SObjectizer.


DV>А где об этом можно больше узнать кроме как в номере журнала?


Ваш вопрос касается только непосредственно SObjectizer.
Но мне кажется, что было бы также полезно познакомиться с литературой, связанной с SObjectizer косвенно. Это могло бы помочь оценить возможности SObjectizer.
Я имею в виду книгу Shlaer, Mellor "Object lifecycles: modeling the world in states". В начале 90-х она была издана на русском языке киевским издательством "Диалектика" под названием "Объектно-ориентированный анализ: моделирование мира в состояниях".
В этой книге детально описан метод ООА, концептуально родственный агентно-ориентированному подходу, примененному в SObjectizer. Евгений (eao197) указывал на него, как на один из "теоретических" источников SObjectizer.
В свое время одно только знакомство с этой книгой помогло мне создать ПО для одного из важнейших компонентов системы безопасности, хотя до того у меня был опыт написания только прикладных программ.
В результате со мной произошло нечто подобное тому, о чем сказал Евгений:

Но главное, что тогда произошло изменение способа мышления лично у меня — я стал испытывать затруднения с решением задач, в которых нельзя было применить агентный подход.

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

Вывод : кроме чтения непосредственно литературы об SObjectizer, можно рекомендовать книгу Шлаер и Меллора. Это может помочь в понимании основных принципов SObjectizer.

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

Хоар
Re[7]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.01.06 11:21
Оценка:
Здравствуйте, GU Glez, Вы писали:

GG>Одно дело "шампунь и кондиционер в одном флаконе", и другое сложное серверное приложение с GUI-интерфейсом. ИМХО, последнее надо бы разделять, чтобы в последствии слить воедино, но ввиде уже двух независимых программ (насколько это возможно) — одно на C++ (SObjectizer), другая на GC-языке. Вот такое мое видение.


Я тоже думаю, что подобные вещи нужно разделять.
Вопрос в том, как их затем объединять. Один способ -- использовать коммуникационные возможности SObjectizer-а (т.н. SOP). Но тогда в GC-приложении должен быть свой SObjectizer. Поэтому я и говорю, что если потребуется и будет заинтересованность, то сделаем Мне просто интересно, захочет ли кто-то программировать в агентах, например, в C#, Python, Ruby или OCaml-е, или Lisp-е.

Второй вариант -- использовать для взаимодействия другие механизмы (SOAP, XML-RPC или CORBA). Тогда GC приложению вообще без разницы, написан ли сервер на C++ и SObjectizer-е или на чем-то еще. Такой вариант можно применять прямо сейчас. И в некоторых проектах у нас так и было.

GG>ЗЫ. Статью, к сожалению, я не читал (еще журнал не дошел), но pdf-ник просмотрел. Возможно отсюда и мое недопонимание сути SObjectizer.


А там короткая выжимка из SObjectizer Book, только отдельное внимание уделено перспективам SObjectizer в сложившихся условиях. В частности, этому посвящен раздел "Ложка дегтя" и особенно "Социально-политические проблемы":

Главная политическая проблема SObjectizer в том, что SObjectizer существует только на C++ и только для C++. В частности, возможности SObjectizer для создания распределенных приложений можно использовать исключительно в С++. Конечно, SObjectizer не мешает использовать в этом же приложении иные способы взаимодействия (CORBA, COM, SOAP, XML-RPC). Но и не помогает. А если в приложение встраивается ручная поддержка CORBA или SOAP, то встает вопрос: “К чему тогда вообще использовать SObjectizer?” И ответ на этот вопрос, особенно когда требуется интероперабельность с написанными на других языках приложениями, часто бывает не в пользу SObjectizer.

Еще одна проблема наследуется SObjectizer от C++. В последнее время у C++ появились очень серьезные конкуренты. С одной стороны, это Java и .Net/C# с огромным количеством готовых библиотек и IDE нового поколения. Очень многих программистов от C++ отталкивает отсутствие настолько же удобных IDE (с автодополнением, автоподсказкой, поддержкой рефакторинга) как IDEA и Eclipse для Java, или VisualStudio+ReSharper для C#. В С++ с этим дела обстоят неважно. A у SObjectizer еще хуже — ведь сейчас нет ни одной IDE, способной поддерживать специфические особенности SObjectizer (хотя бы так, как VisualStudio помогла использовать MFC)...



SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.01.06 11:24
Оценка:
Здравствуйте, AVC, Вы писали:

AVC>Вывод : кроме чтения непосредственно литературы об SObjectizer, можно рекомендовать книгу Шлаер и Меллора. Это может помочь в понимании основных принципов SObjectizer.


На самом деле очень важное дополнение, спасибо, Алексей!


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: SObjectizer: I Love This Game!
От: GU Glez  
Дата: 10.01.06 12:13
Оценка: 1 (1)
Здравствуйте, eao197, Вы писали:
E>Но тогда в GC-приложении должен быть свой SObjectizer.
0. Скорее всего.
E>Поэтому я и говорю, что если потребуется и будет заинтересованность, то сделаем
1. Заинтересованность будет однозначно. Хотя такой синтаксис в назвваниях и обозначениях немного отпугивает (некоторых уже не отпугивает после boost и stl , но для других — тяжеловато читать).

E>Мне просто интересно, захочет ли кто-то программировать в агентах, например, в C#, Python, Ruby или OCaml-е, или Lisp-е.

2. Нет... Пока нет. Не стоЯт еще такие задачи — есть более простые и "родные" способы для достижения подобных целей.

E>Второй вариант -- использовать для взаимодействия другие механизмы (SOAP, XML-RPC или CORBA).

Это правильно!

E>Тогда GC приложению вообще без разницы, написан ли сервер на C++ и SObjectizer-е или на чем-то еще. Такой вариант можно применять прямо сейчас. И в некоторых проектах у нас так и было.

3. Еще бы и хелп небольшой написать. Тогда п.2, возможно отменяется.

E>Главная политическая проблема SObjectizer в том, что SObjectizer существует только на C++ и только для C++. В частности, возможности SObjectizer для создания распределенных приложений можно использовать исключительно в С++. Конечно, SObjectizer не мешает использовать в этом же приложении иные способы взаимодействия (CORBA, COM, SOAP, XML-RPC). Но и не помогает. А если в приложение встраивается ручная поддержка CORBA или SOAP, то встает вопрос: “К чему тогда вообще использовать SObjectizer?” И ответ на этот вопрос, особенно когда требуется интероперабельность с написанными на других языках приложениями, часто бывает не в пользу SObjectizer.

Выделенное и есть один из признаков отсутствия инфраструктуры.

E>Еще одна проблема наследуется SObjectizer от C++. В последнее время у C++ появились очень серьезные конкуренты. С одной стороны, это Java и .Net/C# с огромным количеством готовых библиотек и IDE нового поколения. Очень многих программистов от C++ отталкивает отсутствие настолько же удобных IDE (с автодополнением, автоподсказкой, поддержкой рефакторинга) как IDEA и Eclipse для Java, или VisualStudio+ReSharper для C#. В С++ с этим дела обстоят неважно. A у SObjectizer еще хуже — ведь сейчас нет ни одной IDE, способной поддерживать специфические особенности SObjectizer (хотя бы так, как VisualStudio помогла использовать MFC)...

E>[/q]
К сожалению и к счастью одновременно — это правда.
С уважением,
GU Glez [Джи Ю Глиз]
Re[9]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.01.06 12:21
Оценка:
Здравствуйте, GU Glez, Вы писали:

GG>1. Заинтересованность будет однозначно. Хотя такой синтаксис в назвваниях и обозначениях немного отпугивает (некоторых уже не отпугивает после boost и stl , но для других — тяжеловато читать).


Поживем -- увидим. А что касается нотации, так пока ни у кого проблем не было, быстро привыкают.

E>>Мне просто интересно, захочет ли кто-то программировать в агентах, например, в C#, Python, Ruby или OCaml-е, или Lisp-е.

GG>2. Нет... Пока нет. Не стоЯт еще такие задачи — есть более простые и "родные" способы для достижения подобных целей.

Можно ли раскрыть термин "подобных"? Или пример привести?

E>>Второй вариант -- использовать для взаимодействия другие механизмы (SOAP, XML-RPC или CORBA).

GG>Это правильно!


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: SObjectizer: I Love This Game!
От: GU Glez  
Дата: 10.01.06 12:59
Оценка:
Здравствуйте, eao197, Вы писали:
GG>>[...].
E>Можно ли раскрыть термин "подобных"? Или пример привести?
Хм... пример... Я хотел сказать, что "Подобные" — означает нечто похожее по уровню. Сейчас так вот сразу сказать не могу — не так много я на C# в частности и на .NET вообще. Но суть одна — теперь на .NET можно, очень много сделать в программировании клиент-серверных (и не только) приложений без лишнего гемора (т.е. что думаю, то и пишу не заботясь о низкоуровневых деталях). И все это решается в контексте одной-двух парадигм — что многих и привлекает.

E>

E>Тогда, имхо, часть на SObjectizer усложняется. Появляются два вида взаимодействия -- асинхронное на уровне сообщений, когда границы между процессами размыты, и синхронное.
А это уже интересно. И вообще, чем это плохо или хорошо надо обдумавать и двигаться дальше. По мне так — если есть реальные проекты с GC, то вот на них и надо бы эксперемент проводить; если нет, то что-то стряпать более-менее все равно можно (GUI хотя бы), и вперед... если есть такая возможность, конечно.
С уважением,
GU Glez [Джи Ю Глиз]
Re[11]: SObjectizer: I Love This Game!
От: Dj.ValDen Украина http://ua.linkedin.com/in/dvalchuk
Дата: 10.01.06 19:24
Оценка:
Здравствуйте, AVC, Вы писали:

Спасибо за экскурс

>> Это могло бы помочь оценить возможности SObjectizer.


ничто так не поможет как возможность пощупать

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

Не скажу что жду уже сейчас Задача в которой бы, я думаю, этот фреймворк мне помог была полтора года назад... От Corba я тогда отказался — посчитал слишком тяжёлой и не нужной...

Время движется — может интерессные идеи появятся и этот фреймворк будет востребован... К тому времени думаю он ещё лучше будет
С уважением Denys Valchuk

IMHO чем больше мнений тем оптимальней выбор варианта... :)
Re[12]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.01.06 20:29
Оценка:
Здравствуйте, Dj.ValDen, Вы писали:

DV>ничто так не поможет как возможность пощупать




DV>Так что жду выхода в свет, с туториалом и более менее реалистичным тестовым проектом.


Т.е. имеющийся SObjectizer Book чем-то не достаточен?

И что бы хотелось видеть в качестве тестового проекта?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: SObjectizer: I Love This Game!
От: Dj.ValDen Украина http://ua.linkedin.com/in/dvalchuk
Дата: 11.01.06 20:17
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, Dj.ValDen, Вы писали:


DV>>ничто так не поможет как возможность пощупать


E>)


DV>>Так что жду выхода в свет, с туториалом и более менее реалистичным тестовым проектом.


E>Т.е. имеющийся SObjectizer Book чем-то не достаточен?


может я не правильно выразился
я имел ввиду удобный хелп
Book хорош
Но как книга, а как хелп — нет. Одно другое не исключает — так что книгу не удаляйте
Но удобный хелп, в виде chm, html или ещё чего очень помог бы...

Я ещё сторонник UML описания

E>И что бы хотелось видеть в качестве тестового проекта?


Естественно, что то наглядное и не требующее установки спец оборудования

Может даже и ваши примеры из книжки... Если честно я не люблю смотреть на код как на письмо
Вот письма я пишу чёрным по белому и ничего лишнего — а код предпочитаю с подсветкой синтаксиса
С уважением Denys Valchuk

IMHO чем больше мнений тем оптимальней выбор варианта... :)
Re[14]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.01.06 05:37
Оценка:
Здравствуйте, Dj.ValDen, Вы писали:

DV>я имел ввиду удобный хелп

DV>Но удобный хелп, в виде chm, html или ещё чего очень помог бы...
DV>Вот письма я пишу чёрным по белому и ничего лишнего — а код предпочитаю с подсветкой синтаксиса

Все это есть в виде html Reference, сгенерированного через doxygen. Как мне кажется, весьма подробный.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.01.06 10:38
Оценка: 2 (1)
Здравствуйте, Dj.ValDen, Вы писали:

DV>я имел ввиду удобный хелп


А вот так подойдет?
(оно же в zip-е (1.6Mb)).


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: vdimas Россия  
Дата: 14.02.06 06:54
Оценка: 36 (1)
Здравствуйте, Евгений Охотников, Вы писали:

[примечание: часть переписки, опубликованная здесь по согласию сторон]

ЕО>Там я один вопрос как раз затрагиваю, о возможности портирования SObjectizer на какой-нибудь из managed языков. Поскольку у тебя, как я вижу, вполне лояльное отношение к C#, то интересно было бы узнать, заинтересовался ли бы ты лично SObjectizer-ом, будь он реализован на C#.



Мое мнение насчет реализации подобной наработки на C# примерно такое:
— очень интересный подход диспечеров, в принципе — это краеугольный камень
технологии.

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

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

Из очевидных переделок под дотнет:
— события должны предоставляться делегатами, а не именами.
— сами сообщения лучше регистрировать по типу, а не по имени.
— другая терминология, события в дотнете — это "источник". Ваши send_msg
можно заменить/дополнить подписыванием вашего run-time на интересующие
события объектов.
— то, что вы называете событиями, в дотнете зовется обработчик оного — event
handler.
— возможным станет описывать в конфигурации, объекты какого типа создавать и
как их соединять друг с другом и с диспечером.

Да, кстати, а есть ли в твоей схеме возможность непосредственной стыковки?
Т.е. я имею в виду тот момент, что далеко не всегда требуются услуги
диспетчера. Например, я создаю комплексный объект, который суть модуль
других объектов. И мне может захотеться непосредственным образом соединить
события (обработчики) с сообщениями (событиями и их аргументами).

Ты поднимал вопросы асинхронности обработки сообщений и сетовал, что нет
возможности узнать результат обработки сообщения (или сам факт доставки). В
дотнете есть целый механизм вокруг IAsyncResult и динамического вызова
обработчиков. Далее. Необязательно синхронные вызовы делаются в том же
потоке!!! Можно вызвать событие другом потоке и дождаться завершения
обработки. С точки зрения объемлющего кода это будет выглядеть как
синхронное сообщение. На самом деле, конечно, все должно зависеть от
настроек. Т.е. некоторым событиям (методам) абсолютно все-равно в каком
потоке исполняться. В дотнете подобная доп. информация размечается
атрибутами. Так же можно атрибутами специфировать участие методов (событий)
в подписвании, вместо so_on_subscription().

В общем, если получиться гладко "вшить" диспетчеры в существующую
инфраструктуру .Net, то это все имеет смысл. Т.е. необходимо как-то
предусмотреть систему типов таким образом, чтобы практически одинаково
работать как с непосредственными прямым подключениями (синхронное
распространение событий), так и через диспетчера. Возможно, что
библиотека под дотнет совершенно неузнаваемо изменит первоначальное лицо и будет
прилично отличаться от оной на С++

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

Как я бы предложил попробовать переделать на дотнет: самому выступить в роли
предвзятого юзера-программиста библиотеки и написать несколько
высокоуровневых тестов (сценариев) именно так, как ты бы хотел все это
видеть синтаксически (т.е. максимально кратко и выразительно). Даже факт
компиллируемости необязателен. А я с удовольствием подсказывал бы, как тот
или иной момент выразить на C# в частности или в дотнет вообще.

Насчет — заинтересовался бы лично? Скорее да, если речь пойдет об
организации системы асинхронно взаимодействующих объектов.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 14.02.06 11:53
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Мое мнение насчет реализации подобной наработки на C# примерно такое:

V>- очень интересный подход диспечеров, в принципе — это краеугольный камень
V>технологии.

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

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

Следствием всего этого дела является, имхо, более простой способ создания многопоточных приложений. В чем-то похожий на подход Erlang-а. Но отличающийся от встроенных механизмов поддержки многопоточности в Ada или Java. Если диспетчеры обеспечивают для агента гарантию запуска его обработчиков только на контексте одной нити в один момент времени, то проблем взаимной синхронизации вообще нет. К этому привыкаешь и необходимость ручной работы с mutex-ами или condition variables начинает казаться слишком утомительной

V>Остальное — суть эмуляция вещей, которые сейчас в дотнет делают через

V>reflection или на делегатах. Даже разделение класса и агента похоже вызвано
V>необходимостью отделить декларативные конструкции от "обычных".

Не уверен, что точно понимаю о чем ты говоришь. Понятие агента (и соответственно специального класса agent_t) было выделено по очень простым причинам:
-- чтобы у агента можно было запрашивать специальную информацию (имя класса агента, например);
-- чтобы агентов можно было помещать в одну коллекцию в рамках кооперации агентов;
-- чтобы у агентов можно было вызывать специальные обработчики событий (so_on_subscription, so_on_deregistration).
В общем, в результате обычной декомпозиции ООП

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

Сами же обработчики событий должны быть обычными нестатическими методами. Как раз для манипуляции обработчиками событий вовсе не требовалось выделение отдельного класса agent_t.

V>Из очевидных переделок под дотнет:

V>- события должны предоставляться делегатами, а не именами.

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

V>- сами сообщения лучше регистрировать по типу, а не по имени.


Здесь не все так просто. Один обработчик события может быть подписан на разные типы сообщений. А один тип (C++ класс/структура) может использоваться для реализации разных сообщений.

V>- другая терминология, события в дотнете — это "источник". Ваши send_msg

V>можно заменить/дополнить подписыванием вашего run-time на интересующие
V>события объектов.

Вот это не полностью понимаю. Возможно, из-за слишком поверхностного знания дотнета.

V>- то, что вы называете событиями, в дотнете зовется обработчик оного — event

V>handler.

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

V>- возможным станет описывать в конфигурации, объекты какого типа создавать и

V>как их соединять друг с другом и с диспечером.

Да это, в принципе, и в C++ возможно. Просто во время выпуска первой версии SObjectizer не было времени докрутить эту идею до реализации.

V>Да, кстати, а есть ли в твоей схеме возможность непосредственной стыковки?

V>Т.е. я имею в виду тот момент, что далеко не всегда требуются услуги
V>диспетчера. Например, я создаю комплексный объект, который суть модуль
V>других объектов. И мне может захотеться непосредственным образом соединить
V>события (обработчики) с сообщениями (событиями и их аргументами).

Нет, такого нет и я думаю, что это уже будет не столько SObjectizer. Скорее тебе нужно что-то в стиле libsigc++.

V>Необязательно синхронные вызовы делаются в том же

V>потоке!!! Можно вызвать событие другом потоке и дождаться завершения
V>обработки. С точки зрения объемлющего кода это будет выглядеть как
V>синхронное сообщение. На самом деле, конечно, все должно зависеть от
V>настроек. Т.е. некоторым событиям (методам) абсолютно все-равно в каком
V>потоке исполняться. В дотнете подобная доп. информация размечается
V>атрибутами. Так же можно атрибутами специфировать участие методов (событий)
V>в подписвании, вместо so_on_subscription().

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

V>В общем, если получиться гладко "вшить" диспетчеры в существующую

V>инфраструктуру .Net, то это все имеет смысл. Т.е. необходимо как-то
V>предусмотреть систему типов таким образом, чтобы практически одинаково
V>работать как с непосредственными прямым подключениями (синхронное
V>распространение событий), так и через диспетчера. Возможно, что
V>библиотека под дотнет совершенно неузнаваемо изменит первоначальное лицо и будет
V>прилично отличаться от оной на С++

Очень на то похоже

V>Но это не страшно, если останется суть. А суть, насколько я понял, в

V>организации механизмов асинхронной доставки сообщений подписчкам. Большое
V>количество другой, дополнительной функциональности в SO лишь обслуживает
V>основную задачу, решая различные технические моменты. В общем, в дотнет
V>многие из тех моментов уже решены, поэтому библиотека может выйти гораздо
V>компактнее.

Очень возможно. Особенно с учетом автоматической сборки мусора в дотнете. Собственно, в этом и привлекательность потрирования SObjectizer в managed среды, что многие вещи там уже готовы или проще. Смущает возможная производительность, т.к. вызов обработчика события -- это весьма существенный оверхед. Хотя, судя по общему мнению, JIT собирается творить чудеса

Тут важно другое оценить -- заинтересованы ли пользователи managed языков в подобных инструментов. Насколько я могу судить, многие разработки на Java ведутся в рамках Web-технологий и по разным существующим спецификациям (J2EE со товарищи), на готовых фреймворках и серверах приложений. Поэтому я не очень понимаю, заинтересуется ли кто-нибудь из Java разработчиков чем-то подобным SObjectizer-у. У C#, имхо, список возможных предметных областей гораздо шире, а список готовых инструментов -- наоборот.

V>Насчет — заинтересовался бы лично? Скорее да, если речь пойдет об

V>организации системы асинхронно взаимодействующих объектов.

Спасибо за столь развернутое мнение.


Еще вопрос: а как бы ты оценил саму статью? Стиль, форму подачи материала, его объем?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: SObjectizer: I Love This Game!
От: mrozov  
Дата: 14.02.06 12:53
Оценка: 24 (1) +2 :))
Здравствуйте, Аноним, Вы писали:

А>Ребята не имею ничего личного к автору,

Я имею — в хорошем смысле.
А>при общении с ним убеждался в его проффесионализме,
Аналогично.
А> Софт, написанный на этом движке, (работал с ним лично)
Аналогично.
А>это один единый гармонично работающий глюк. Не поддающийся логичному лечению
У меня работает, как часы. Ни одного глюка за несколько лет не замечено. Может, дело-таки не совсем в Евгении?
Re: SObjectizer: I Love This Game!
От: mrozov  
Дата: 16.02.06 13:01
Оценка: 24 (1)
Здравствуйте, Евгений Охотников, Вы писали:

Привет!

Сразу — концепция управления потоками мне очень понравилась.
Концепция управления состояниями очень не понравилось.
С последнего и начну.

С моей точки зрения, как раз взаимодействие на основе сообщений создает идеальный фундамент для реализации состояний в виде отдельных классов — в них можно реализовывать те и только те методы, которые имеют смысл для данного состояния.
Т.е. идеальный в моих глазах подход выглядит так — агент — это идентификатор. Состояние — это объект, который в данный момент зарегистрирован под этим идентификатором. Набор методов вида
ProcessMessage(Message msg)

где вместо Message задается имя конкретного подкласса, как раз и является описанием и состояния и событий, которые оно в состоянии обрабатывать. Это наиболее естественный способ создания такого класса (событие — обработчик) и способ определения допустимых сообщений в одном флаконе.
А вот на отсутствие обработчика для сообщения система должна реагировать в обязательном порядке.
Благо это не сложно сделать.

Также хотелось бы заметить, что есть и другие варианты решения подобной задачи. Например — com+ events. Там есть две модели обработки — синхронная (гут) и асинхронная на основе MQ (даже лучше).
Соответственно, в идеальной системе такого рода эти модели было бы неплохо предусмотреть. Опять же, хорошо бы иметь возможность отследить судьбу асинхронной обработки.

На сим пока закончу, ибо выдохся.

Только один поинт — приплетать сюда events из .net я бы не стал. Не нужны они тут.
Re[3]: SObjectizer: I Love This Game!
От: vdimas Россия  
Дата: 16.02.06 20:26
Оценка: 11 (1)
Здравствуйте, eao197, Вы писали:

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


Нет, все же программистом
Просто программист использует "другой" инструмент. Знаешь, насчет той статьи, я бы добавил туда более четкого позиционирования технологии (может быть в ущерб подробностям реализации). Т.е., прежде, чем что-то обсуждать, было бы неплохо понять — что именно мы собираемся обсуждать. SObjectizer — это инструмент. Инструмент для чего? Вон ниже mrozov вообще выдвигает свои соображения насчет распределенной жизни объектов и их состояний. Только мне его рассуждения показались очень уж частными, т.е. опять же — моментами, с которыми сталкивался он лично, но которые не обязательно хорошо подходят для других задач.

E>Второй краеугольный камень -- это взаимодействие на основе сообщений. Может быть даже он главнее.


Женя, я делаю акцент на том, что рассматривал твой вопрос с т.з. реализации SObjectizer на дотнет. А в нем взаимодействие на основе сообщений УЖЕ реализовано. Т.е. мы можем вызывать методы асинхронно (просто посылать сообщение), синхронно (послать сообщение и дожаться ответа), и откликаться на события, на которые подписаны (на одно событие может быть подписано куча подписчиков). Событие — это обратный вызов (call back), т.е. все то, что делает твоя система. Однако, при этом подробности потоков исполнения, блокировки и пр. реализованы лишь в 2-х моделях: STA и MTA. Твои диспеччеры позволяют создавать произвольное количество "групп" — аппартаментов, и позволяют создавать диспеччеры, которые этими аппартаментами управляют. Вот на какой именно уровень ты залез. И мне это кажется весьма любопытным. Более того, есть еще один момент. В дотнет нужно явно указывать — синхронно или асинхронно я вызываю события. Мне бы хотелось... вынести это из вызывающего кода, что-ли.

Далее. Ты все время говоришь об взаимодействии на основе сообщений. Вообще-то считается, что вызов метода объекта — это и есть посылка ему некоего сообщения. (Обратный вызов, т.е. событие для подписчика, разумеется тоже). Просто в твоей системе все делается через обратный край воронки: SendMsg(), а в дотнете эта воронка двухсторонняя: с обоих сторон обычные вызовы обычных методов, а между ними — транспорт с пакетами сообщений, STA и MTA диспетчеры.

Согласись, что SendMsg("ClosePipe", param) проигрывает этому: ClosePipe(param) сразу по многим пунктам.

Одиин из них: я вообще с очень давних времен не люблю строковые константы в коде. Когда их несколько сотен (илил даже несколько тысяч) — ими невозможно управлять, в то время как сигнатурами методов помогают управлять современные IDE.


E>Во-первых, поэтому возможно само существование диспетчера. Во-вторых, появляется возможность делать относительно прозрачную распределенность.


Да, для С++ так и есть. На отсутствие НОРМАЛЬНЫХ сетевых высокоуровневых библиотек для С++ Страуструп жаловался более 10 лет назад, но воз и ныне там, к большому сожалению. Для дотнета распределенность достигается весьма прозрачно. Слово прозрачно — ключевое. Для алгоритма не имеет значения, с локальным объектом идет работа, или с его удаленным прокси. Правда есть одна оговорка — это прозрачно до тех пор, пока имеющиеся возможности устраивают. Как только чего-то нехватает в дотнет, то приходится довольно много делать "ручками", даже в нем. (Собственно, как и везде — неудивительно).

Ценность твоего опыта — в нескольких реальных проектах (насколько я понял) на своей технологии. Ты уже разглядывал в упор все эти подводные камни, о которых большинство даже сильных спецов знает лишь благодаря своей эрудиции.

В общем, прежде, чем обсуждать технические моменты, а главное — сам вопрос: "нужен ли SObjectizer дотнету", ты лично (да именно ты и только ты ) должен собрать как можно больше информации о том, как аналогичное сделано в этом дотнете и какие именно работы по организации распределенных систем были бы полезны/интересны дотнетному сообществу.


Смотри, как сделать простейшую распределенную систему на дотнете, которая очень близко копирует именно твою архитектуру:

// это сигнатура сообщения
public delegate void CurrencyChangedMsg(object sender, string currencyCode, double currency);

// это наш главный диспетчер
public interface ICurrencyMarket {
    event CurrencyChangedMsg CurrencyChanged;
}


Затем, интересующие агенты получают каким-либо образом ссылку на экземпляр CurrencyMarket, и подписываются на сообщения, например так:
public class AirportTabloid : Form {

blah blah blah 

    void ConnectToCurrencyMarkets() {
        // подписываемся на события от 3-х разных диспетчеров во всем мире.
        ICurrencyMarket market = (ICurrencyMarket)RemotingServices
            .Connect("tcp://currency.market.com:8085/Dispatcher", typeof(ICurrencyMarket))
        market.CurrencyChanged += OnCurrencyChanged;

        market = (ICurrencyMarket)RemotingServices
            .Connect("http://www.currency.jp/currency", typeof(ICurrencyMarket))
        market.CurrencyChanged += OnCurrencyChanged;

        market = (ICurrencyMarket)RemotingServices
            .Connect("iiop://privatbank.ru:11500/Dispatcher", typeof(ICurrencyMarket))
        market.CurrencyChanged += OnCurrencyChanged;
    }

    void OnCurrencyChanged(object sender, string currencyCode, double currency) {
        TextBox tb = FindByCurrencyCode(currencyCode);
        if(tb!=null)
            tb.Text = currency.Format("C");
    }

}


(обрати внимание на разные заголовки URL )

Видишь, в чем основное отличие от твоей имплементации на С++? В том, что программист орудует НЕПОСРЕДСТВЕННО прикладными абстракциями, а не их строковыми идентификаторами.


E>Следствием всего этого дела является, имхо, более простой способ создания многопоточных приложений. В чем-то похожий на подход Erlang-а. Но отличающийся от встроенных механизмов поддержки многопоточности в Ada или Java. Если диспетчеры обеспечивают для агента гарантию запуска его обработчиков только на контексте одной нити в один момент времени, то проблем взаимной синхронизации вообще нет. К этому привыкаешь и необходимость ручной работы с mutex-ами или condition variables начинает казаться слишком утомительной


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

V>>Остальное — суть эмуляция вещей, которые сейчас в дотнет делают через

V>>reflection или на делегатах. Даже разделение класса и агента похоже вызвано
V>>необходимостью отделить декларативные конструкции от "обычных".

E>Не уверен, что точно понимаю о чем ты говоришь. Понятие агента (и соответственно специального класса agent_t) было выделено по очень простым причинам:

E>-- чтобы у агента можно было запрашивать специальную информацию (имя класса агента, например);
E>-- чтобы агентов можно было помещать в одну коллекцию в рамках кооперации агентов;
E>-- чтобы у агентов можно было вызывать специальные обработчики событий (so_on_subscription, so_on_deregistration).
E>В общем, в результате обычной декомпозиции ООП

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


V>>Из очевидных переделок под дотнет:

V>>- события должны предоставляться делегатами, а не именами.

E>Мне кажется, что имена как раз добавляют декларативности.


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


E>Здесь не все так просто. Один обработчик события может быть подписан на разные типы сообщений. А один тип (C++ класс/структура) может использоваться для реализации разных сообщений.


В общем, посмотри на пример. В дотнет ты можешь подписаться на событие, если сигнатура твоего метода совпадает с сигнатурой события. Т.е. ты можешь подписать на один и тот же метод-обработчик события от РАЗНЫХ источников совершенно разного типа (в примере указан один тип для 3-х удаленных серверов, но это могли бы быть совершенно разные 3 типа), которые могут плеваться совершенно разными типами сообщений. Главное — чтобы совпадали сигнатуры.


V>>- другая терминология, события в дотнете — это "источник". Ваши send_msg

V>>можно заменить/дополнить подписыванием вашего run-time на интересующие
V>>события объектов.

E>Вот это не полностью понимаю. Возможно, из-за слишком поверхностного знания дотнета.


Я в примере показал как это выглядит внешне. Ну а как оно выглядит внутренне — это надо знакомится с System.Runtime.Remoting в mscorlib, лучше всего рефлектором + MSDN.


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


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

V>>- возможным станет описывать в конфигурации, объекты какого типа создавать и

V>>как их соединять друг с другом и с диспечером.

E>Да это, в принципе, и в C++ возможно. Просто во время выпуска первой версии SObjectizer не было времени докрутить эту идею до реализации.


В дотнет это будет просто как никогда. В моем примере мне бы хотелось вместо хардкодного тела метода ConnectToCurrencyMarkets() описать все это в стандартном файле конфигурации... Неплохо так же иметь к нему визуальный редактор

V>>Да, кстати, а есть ли в твоей схеме возможность непосредственной стыковки?

V>>Т.е. я имею в виду тот момент, что далеко не всегда требуются услуги
V>>диспетчера. Например, я создаю комплексный объект, который суть модуль
V>>других объектов. И мне может захотеться непосредственным образом соединить
V>>события (обработчики) с сообщениями (событиями и их аргументами).

E>Нет, такого нет и я думаю, что это уже будет не столько SObjectizer. Скорее тебе нужно что-то в стиле libsigc++.


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


E>С синхронностью все не так просто

E>Если синхронный вызов делается из нити, не относящейся к диспетчерам SObjectizer, то особых проблем нет. Но если синхронный вызов идет из обработчика событий агента, то в результате можно получить тупик, если в конце-концов потребуется задействовать нить диспетчера, на которой был инициирован синхронный вызов. Контроль и диагностирование таких тупиков может быть слишком дорогой операцией (при том, что потенциально она будет слишком редкой).

Я же говорю — тебе виднее
Твой опыт весьма уникален. Но я так же уверен, что есть возможности для разруливания всего этого дела. Мне тут же в голову полезли детали, но не хочу сейчас их обсуждать, ибо это будет очень сыро с моей стороны (навскидку).

E>Тут важно другое оценить -- заинтересованы ли пользователи managed языков в подобных инструментов. Насколько я могу судить, многие разработки на Java ведутся в рамках Web-технологий и по разным существующим спецификациям (J2EE со товарищи), на готовых фреймворках и серверах приложений. Поэтому я не очень понимаю, заинтересуется ли кто-нибудь из Java разработчиков чем-то подобным SObjectizer-у. У C#, имхо, список возможных предметных областей гораздо шире, а список готовых инструментов -- наоборот.


Далеко не всем будет интересно, но заинтересованные найдутся, разумеется. Пока что люди заинтересованы не столько тактико-техническими характеристиками своих систем, сколько самим фактом реализации таких систем. А для этого и встроенных возможностей дотнета вполне хватает. А вот когда захочется делать эффективно, но по прежнему просто — потребуютс тулзы, типа обсуждаемого.
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 17.02.06 12:28
Оценка:
Здравствуйте, vdimas

Дима, интересный ответ получился, нужно его покурить... Пока же несколько простых уточнений.

E>>Здесь не все так просто. Один обработчик события может быть подписан на разные типы сообщений. А один тип (C++ класс/структура) может использоваться для реализации разных сообщений.


V>В общем, посмотри на пример. В дотнет ты можешь подписаться на событие, если сигнатура твоего метода совпадает с сигнатурой события. Т.е. ты можешь подписать на один и тот же метод-обработчик события от РАЗНЫХ источников совершенно разного типа (в примере указан один тип для 3-х удаленных серверов, но это могли бы быть совершенно разные 3 типа), которые могут плеваться совершенно разными типами сообщений. Главное — чтобы совпадали сигнатуры.


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

И еще один момент -- сообщения, в отличии от сигнатур методов, проще расширять.

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


V>Хм... а разве не может быть так, что в какой-то момент на какое-то событие нет заинтересованных обработчиков (агентов)? Вполне нормальная ситуация...


Так в том-то и дело, что событие -- это факт реакции конкретного агента на конкретное сообщение. Если агент не заинтересован в сообщении или агента просто нет, то нет и события, а сообщения уходят либо в пустоту, либо другим агентам.

E>>Нет, такого нет и я думаю, что это уже будет не столько SObjectizer. Скорее тебе нужно что-то в стиле libsigc++.


V>И да и нет... Я ведь не зря говорил про "гладкую" стыковку с механизмом дотнета. В общем, оба способа должны внешне выглядеть одинаково. И не важно как это будет называться, SObjectizer или boost::signal. Какой конкретно механизм используется для каждого конкретного соединения диспетчера и агента должно зависеть только лишь от их взаимного расположения и суммарных взаимных политик и настроек.


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game!
От: vdimas Россия  
Дата: 17.02.06 13:29
Оценка: 10 (1)
Здравствуйте, eao197, Вы писали:

V>>В общем, посмотри на пример. В дотнет ты можешь подписаться на событие, если сигнатура твоего метода совпадает с сигнатурой события. Т.е. ты можешь подписать на один и тот же метод-обработчик события от РАЗНЫХ источников совершенно разного типа (в примере указан один тип для 3-х удаленных серверов, но это могли бы быть совершенно разные 3 типа), которые могут плеваться совершенно разными типами сообщений. Главное — чтобы совпадали сигнатуры.


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


Да, в моей терминологии это было бы — несколько "входных точек", то бишь, несколько методов, по одному на каждую сигнатуру. Знаешь, как подобное разруливается в Windows.Forms? Там используется одна сигнатура на большинство событий, вот она:
public delegate void EventHandler(object sender, EventArgs e);


Итак, sender — кто угодно, EventArgs — абсолютно пустой класс, просто корень базовой иерархии для других аргументов событий. Понятное дело, что через эту схему можно прогнать произвольное кол-во типов сообщений, совместимых с одной и той же сигнатурой "точки входа", то бишь метода-обработчика (event handler).

Но мне подобные схемы не нравятся так же, как использование void* в С++. Пусть MS выбрала именно такую сигнатуру по уважительной причине (тонны типов конролов и тонны сообщений), свое ПО я предпочитаю выражать во вполне конкретных типах и напрягать компилятор на первоначальную проверку логики программы, то бишь использовать типизацию.

E>И еще один момент -- сообщения, в отличии от сигнатур методов, проще расширять.


Ок, как насчет еще большей модификации приведенной схемы:
public class MsgBase {}

public delegate void MsgHandler(MsgBase msg); // вот такая сигнатура


Но мне такая схема совершенно не нравится. Ведь все-равно внутри обработчика придется делать некий swtch-case (if-else) по типу сообщения и обрабатывать каждый тип по-своему. Так почему бы не выполнить явную функциональную декомпозицию и не подписать разные сообщения сразу на "нужные" точки входа?

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

Да, важный момент. Насколько я понял, в твоих реальных системах ты часто использовал только лишь имя (идентификатор) сообщения. Да, это важный класс сообщений, которые интересны самим только фактом своего возникновения.
public delegate void Notify();

public IMyServer {
    event Notify Event1, Event2, Event3 ... EventN;
}

public MyClient {

    void Connect(IMyServer server) {
        server.Event1+=OnEvent1To3;
        server.Event2+=OnEvent1To3;
        server.Event3+=OnEvent1To3;

        server.Event4+=OnEvent4ToN;
        ...
        server.EventN+=OnEvent4ToN;
    }

    // здесь мы обрабатываем одну группу сообщений
    void OnEvent1To3() { ... }

    // здесь - другую
    void OnEvent4ToN() { ... }
}


Итак, у нас есть одна сигнатура — пустая, и куча событий (терминология дотнет), использующих эту сигнатуру. И есть 2 обработчика событий, OnEvent1To3 мы подписали первые 3 события, на OnEvent4ToN — остальные.

Согласись, довольно-таки гибко и главное, подобный код — самодокументируем по сути, его легко понять. Я уверен, что ты все понял.

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


V>>Хм... а разве не может быть так, что в какой-то момент на какое-то событие нет заинтересованных обработчиков (агентов)? Вполне нормальная ситуация...


E>Так в том-то и дело, что событие -- это факт реакции конкретного агента на конкретное сообщение. Если агент не заинтересован в сообщении или агента просто нет, то нет и события, а сообщения уходят либо в пустоту, либо другим агентам.


Понятно, опять расхождение в терминологии. Я тебя понял, я примерно это и имел в виду.


V>>И да и нет... Я ведь не зря говорил про "гладкую" стыковку с механизмом дотнета. В общем, оба способа должны внешне выглядеть одинаково. И не важно как это будет называться, SObjectizer или boost::signal. Какой конкретно механизм используется для каждого конкретного соединения диспетчера и агента должно зависеть только лишь от их взаимного расположения и суммарных взаимных политик и настроек.


E>Дело в том, что сейчас в SObjectizer есть механизм т.н. insend-событий -- это когда SObjectizer вызывает обработчик события прямо внутри send_msg и на контексте той же нити. Тот, кто вызывает send_msg даже не знает, что insend-события уже отработали. Для отправителя сообщения внешне ничего не изменилось.


Ну, замечательно... Для GUI этот способ весьма востребован.
Re: SObjectizer: I Love This Game!
От: VVB16 Россия  
Дата: 17.02.06 13:53
Оценка:
Здравствуйте, Евгений Охотников, Вы писали:

Жаль что при создании SObjectizer вы сразу не стали использовать ACE.
Там как раз ActiveObjects есть и механизмы для организации их работы.
Re[6]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 17.02.06 14:36
Оценка:
Здравствуйте, vdimas, Вы писали:

E>>И еще один момент -- сообщения, в отличии от сигнатур методов, проще расширять.


V>Ок, как насчет еще большей модификации приведенной схемы:

V>
V>public class MsgBase {}

V>public delegate void MsgHandler(MsgBase msg); // вот такая сигнатура
V>


Как только появляется сигнатура с одним параметром msg, то сразу напоминает SObjectizer.

V>Но мне такая схема совершенно не нравится. Ведь все-равно внутри обработчика придется делать некий swtch-case (if-else) по типу сообщения и обрабатывать каждый тип по-своему. Так почему бы не выполнить явную функциональную декомпозицию и не подписать разные сообщения сразу на "нужные" точки входа?


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


В SObjectizer от этого так же можно защититься, для этого специальный способ описания события существует. И используется.

Да я понимаю о чем ты говоришь. Это на самом деле так (опять вспоминаются вечные споры динамическая типизация+duck typing против статической типизации).

Хотя в данном конкретном случае я говорил о добавлении в MsgBase новых полей, а не новых наследников. По аналогии с протоколами -- новая версия протокола остается совместимой с предыдущей версией, но добавляет новые поля, которые старая версия может проигнорировать. Подобное расширение, перенесенное на методы будет означать, что каждое новое расширение нужно будет добавлять новый метод-отправитель сообщения:
ClosePipe(pipeId);
ClosePipe(pipeId, flushMode);
ClosePipe(pipeId, flushMode, flushTimeout);
ClosePipe(pipeId, reopenTimeout);
ClosePipe(pipeId, flushMode, flushTimeout, reopenTimeout);

Такие вещи в динамических языках удобнее выглядят, там параметры местами менять можно:
close_pipe pipe_id
close_pipe pipe_id, :flush_mode => mode
close_pipe pipe_id, :flush_timeout => tv, :flush_mode => mode
close_pipe pipe_id, :reopen_timeout => tv
close_pipe pipe_id, :flush_mode => mode, reopen_timeout => tv_reopen, :flush_mode => tv_flush


По поводу типизации я думал вот чего сделать в свое время, чтобы отсылка была не через send_msg напрямую, а чтобы в каждое сообщение отсылалось с помощью статического метода в типе сообщения:
msg_close_pipe::send( pipe_id, flush_mode, flush_timeout );
msg_close_pipe::send( pipe_id, flush_mode, flush_timeout, reopen_timeout );

а все обращения к send_msg скрывались бы внутри send().

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

V>Согласись, довольно-таки гибко и главное, подобный код — самодокументируем по сути, его легко понять. Я уверен, что ты все понял.


Угу, понял. Вот так это могло бы выглядеть в SObjectizer на C++.
so_4::rt::evt_subscr_t from1to3;
from1to3.add( "server", "event_1" );
from1to3.add( "server", "event_2" );
from1to3.add( "server", "event_3" );
so_4::api::subscribe_event( "a_my", "evt_1to3", from1to3,  so_4::rt::evt_subscr_t::e_change_all );

so_4::rt::evt_subscr_t from4toN;
from4toN.add( "server", "event_4" );
from4toN.add( "server", "event_4" );
so_4::api::subscribe_event( "a_my", "evt_4toN", from4toN, so_4::rt::evt_subscr_t::e_change_all );


Дима, у меня предложение: пока тему статической vs динамической типизации не развивать.
Я понял твою точку зрения. Но есть и еще такой фактор, что используемый сейчас в SObjectizer подход позволяет добавить в статически типизированный C++ какие-то черты динамической типизации. Иногда полезно. Хотя во мне может еще отставаться остаточное впечатление (стереотип) с тех времен, когда у предшественника SObjectizer-а был визуальный дизайнер, а все конструирование осуществлялось как прописывание имен в соответствующих формочках.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 17.02.06 14:45
Оценка:
Здравствуйте, VVB16, Вы писали:

VVB>Жаль что при создании SObjectizer вы сразу не стали использовать ACE.


Сейчас разрабатывается обновленная версия SObjectizer, в которой ACE как раз используется в качестве нижнего уровня.

VVB>Там как раз ActiveObjects есть и механизмы для организации их работы.


Дело в том, что ACE и SObjectizer предоставляют разные подходы к организации работы активных объектов. Подход ACE, имхо, ориентирован в первую очередь на обработку потоков данных из коммуникационых каналов. И все преимущества подхода ACE начинают сказываться, когда применяются высоуровневые фреймворки ACE, т.к. Task и Streams.

SObjectizer же предназначен для обработки логики в случаях, когда эта логика может описываться конечными автоматами. И здесь SObjectizer по сравнению с ACE дает некоторое удобство программисту, т.к. в ACE все ообщение через очерди сообщений нужно делать вручную (начиная от организации самих очередей и операций записи/чтения, заканчивая необходимостью вручную упаковывать данные в ACE_Message_Block). А в SObjectizer можно легко обмениваться прикладными сообщениями без знания этих низкоуровневых деталей.

Так же, ACE предлагает очень низкоуровневые средства для организации распределенных приложений. Нужно будет самостоятельно программировать весь data flow и преобразование данных. SObjectizer здесь так же серьезно упрощает работу программисту.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: vim  
Дата: 18.02.06 10:35
Оценка: 13 (1)
Мне понравилась статья в RSDN о SObjectizer и собственно сама
платформа. Хотелось бы узнать можно получить SObjectizer для
разработки не комерческих продуктов в качестве одного из компанентов,
к примеру учебно-исследовательские работы, диплом.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.02.06 13:11
Оценка:
Здравствуйте, vim, Вы писали:

vim>Мне понравилась статья в RSDN о SObjectizer и собственно сама

vim>платформа. Хотелось бы узнать можно получить SObjectizer для
vim>разработки не комерческих продуктов в качестве одного из компанентов,
vim>к примеру учебно-исследовательские работы, диплом.

Приятно слышать такие слова. Спасибо за отзыв.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: Alex Alexandrov США  
Дата: 17.03.06 18:55
Оценка:
Здравствуйте, Евгений Охотников, Вы писали:

ЕО>Статья:

ЕО>SObjectizer: I Love This Game!
Автор(ы): Евгений Охотников
Дата: 31.03.2006
Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


ЕО>Авторы:

ЕО> Евгений Охотников

ЕО>Аннотация:

ЕО>Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.

Линк http://msk.nestor.minsk.by/kg/2000/kg0009/kg03710.html — мертвая
It's kind of fun to do the impossible (Walt Disney)
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.03.06 06:09
Оценка:
Здравствуйте, Alex Alexandrov, Вы писали:

AA>Линк http://msk.nestor.minsk.by/kg/2000/kg0009/kg03710.html — мертвая


Да, линк поменялся уже после выхода журнала из печати. Вот правильный (пока?) http://msk.nestor.minsk.by/kg/2000/37/kg03710.html

2rsdn team: а как можно исправлять ошибки/ссылки в уже опубликованной статье?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: SObjectizer: I Love This Game!
От: Alexmoon Украина  
Дата: 31.03.06 09:32
Оценка: 18 (3) :)
Здравствуйте, VladD2, Вы писали:

VD>1. Уверен, что скорость продукта в большей степени зависит от качества кода и алгоритмов. Ява даст оверхэд в среднем процентов в 20-70. Это не те цифры.

VD>2. Кто сказал, что скорости не достаточно, а надежности избыточно? Вот аноним намекает на то, что как раз недостаточно надежности.
VD>3. Перефразирую себя. Написать один сервер окуратно на С++ задача решаемая. Если потратить много денег/времени на тестирование, то он без сомнения будет работать. Но вот писать прикладной код на С++ — это маразм. На это способны еденицы. И если ты хочешь чтобы твой сервер был востребован, то его АПИ должен быть ориентирован на безопасный язык!
1. От качества кода зависит абсолютно все и в том числе гарантированная надежность. Оверхед в 20-70 процентов — это для вас лично не те цифры. Напомню еще раз у всех свои принципы отношения к подобным вещам и если исходить из принципа что софт должен быть написан быстро и как можно более дешевым программистом, то все — не те цифры, кроме возможности чтобы он вообще что либо написал.
2. Не для кого не секрет, что в нашей проф. среде есть два принципиально разных подхода — это кодирование и программирование. Вторые делают гарантированно надежные приложения на С++, а первые не сделают их никогда. Это условно. Читайте между строк, если кого то это обидело. Язык и платформа — это не цель а средство.
3.Если писать прикладухи на С++ будет человек не имеющий отношения к программированию — тогда и только тогда это маразм. Писать гарантированно надежные, не боюсь писать этого словосочетания, на С++ способны далеко не идиницы. Проблема не в языке, а в том что мы разленились совсем. С++ в этом случае как раз дает намного более удачную гибкость при разработке. Мои друзья перешедшие полностью под NET привожят лишь одно достойное утверждение и в душе они сами с этим согласны — "думать надоело." Это хоть и грубо, но мы все боимся правды как огня.
4. Если ты хочешь чтобы твой сервер был востребован, то

зависит от качества кода и алгоритмов

, а не лишь утверждение что

то его АПИ должен быть ориентирован на безопасный язык

. Последняя цитата связана с востребованностью точно так же, как заметил автор ниже Dj.ValDen:

"Вы проиграли в футбол потому, что у вас правостороннее движение."


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

Наводящий вопрос. Что значит словосочетание море кода в наше время при компонентном, библиотечном и т.д. подходе. Такие утверждения можно голословно привязать и к твоим подходам.

[skip]

E>> Существует масса кода на C/C++, которые работают в режиме 24x7, не глючат и не падают. Существует не мало кода на Java, который должен был бы работать в режиме 24x7, но падает.

VD>Ой, позволь не поверить. Думаю что работающего прикладного серверного кода написанного на Яве куда больеше чем написанного на С++.
А ты поверь. Почему можно делать надежный софт на чем угодно я написал выше, а насчет последнего приложения, позволю себе пошутить, да ровно на одну больше, но о чем это говорит? И не отвечай что о надежности. Ты сам знаешь, что это не так.

E>>Разговоры о том, что на C++ нельзя писать надежные программы -- это от лукавого.


VD>Гарантированно надежные — это факт. Ну, да я не о том. Я о общей надежности решений. Если бы твои слова были бы правдой, то веб-приложения писались бы на С++, а Ява никогда не заняла бы такой огромный рынок.

Это факт(это не подтверждение твоих слов). И так всем понятно о чем я, но писать больше смысла нет. Они не пишутся на С++ совершенно по другой причине. Лепить к недостатку С++ чистое количество — это не разговор. Интересно какого одобрения ты ожидал утверждая именно так.

E>> Очень похожи на разговоры о том, что на динамических языках нельзя писать надежные программы.


VD>Что считать динамическими? На динамически типизированных? Все завист от сложности системы. Монолитные огромные наврено сложно писать. А нечто вроде веб-приложений можно. Вот только при этом языка должен быть безопасным. Большинство динамически типизированных языко этому требованию удовлетворяют. А С++ — нет. Потому он и не пригоден для разработки прикладного серверного софта. То жест потенциально конечно и на ассемблере можно написать код без ошибок. Но чем больше объем системы, чем больше и разношерстнее команда разрботчиков, чем меньше сроки, тем меньше вероятность получения надежного продукта. Причем в отличии от типобезопасных языков не факт, что удастся за счет одного-двух талатнливых программистов быстро исправлять глуюки.

Чем разношорстнее команда разработчиков, тем сложнее подходить к проблеме проектирования интерфейса, самого продукта и "тем меньше сроки" никакого отношения к этому не имеет. То как сейчас подходят к проблеме работы с удаленными как ты говоришь разношерстными командами — не показатель того, что С++ менее применим к подобным задачам чем другие языки, а лишь показатель того, что это делается через всем известное место. Мне не 10 лет и я знаю что говорю. И даже в таких условиях хорошо подобранной команде — это удается сделать на ++.


E>> И то и другое не верно. Скорее C++ не облегчает написание надежных программ. Поэтому первый же дятел-разработчик легко вызывает крах большой системы.

VD>Знашь, я вот сомтрю вокур и удивляюсь. С кем не заговоришь так он не дятел. А вокруг одни дятлы, дятлы, дятлы...
No comments.

1. Здесь обсуждение конкретной статьи, а не продолжние сериала StarWars. Первые пару постов я и так держал себя в руках. Мы все взрослые люди и знаем что говорим. Раз ты вызвался, то я ответил на вопрос. Я старался быть как можно более корректным.
2. Чтобы ты не подумал плохого, я тебя очень уважаю как коллегу. Ничего лишнего. Только мысли вслух. Я вернусь к обсуждению, только лишь по поводу статьи, если будет что сказать нового.
Re: SObjectizer: на SourceForge
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 31.03.06 10:40
Оценка:
ЕО>Статья:
ЕО>SObjectizer: I Love This Game!
Автор(ы): Евгений Охотников
Дата: 31.03.2006
Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


ЕО>Аннотация:

ЕО>Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.

Текущая бета версия последней, разрабатываемой сейчас, версии SObjectizer доступна на SourceForge под BSD лицензией.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: Аноним  
Дата: 01.04.06 12:44
Оценка: +1
Здравствуйте, Евгений Охотников, Вы писали:

ЕО>SObjectizer является моим любимым инструментом.


Могу рассказать одну историю.
Жил-да-был один студент. Настала пора сдавать экзамен по программированию. Билет ответил, задачу решил — ждет пятерку. И тут препод спрашивает: а почему Вы при решении использовали очередь, а не стек? Студент честно отвечает: а я зачетную задачу на очередях делал, и вообще у меня очереди — любимый инструмент. Посмотрел на него преподаватель и сказал: у программиста не должно быть "любимых" инструментов, он должен использовать наиболее целесообразный инструмент для каждой решаемой задачи. И поставил студенту 4, а не 5.

ИМХО, статья описывает восторг создателя от собственной разработки. Но это еще полбеды. Найденное решение "заперло" автора в рамках одной парадигмы — как он сам признается, ему стало трудно решать те задачи, где неприменим агентный подход. Могу лишь советовать автору прочитать пару книг о паттернах и убедиться, что предлагаемое им решение — не что иное как реализация нескольких (но далеко не всех!) классических методик. Нужно отойти в сторону и взглянуть непредвзято

P.S. Добавлю, что тем студентом был я, и преподавателю тому ныне весьма благодарен.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.04.06 13:04
Оценка: +2
Здравствуйте, Аноним, Вы писали:

А>ИМХО, статья описывает восторг создателя от собственной разработки. Но это еще полбеды. Найденное решение "заперло" автора в рамках одной парадигмы — как он сам признается, ему стало трудно решать те задачи, где неприменим агентный подход.


Поэтому я решаю задачи, в которых агентный подход применим. И использую для решения SObjectizer.
Разве я в статье предлагал писать на SObjectizer Web-приложения (хотя это вполне возможно)? Или расчет распределения температуры на лопастях газовой турбины? Или разработку компилятора C++ на SObjectizer делать? Что-то не припоминаю такого.

A>Могу лишь советовать автору прочитать пару книг о паттернах и убедиться, что предлагаемое им решение — не что иное как реализация нескольких (но далеко не всех!) классических методик. Нужно отойти в сторону и взглянуть непредвзято


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

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

Так что может отойдем от общих рекоментаций по поводу полезности просвящения и попробуем поговорить более предметно?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Конструктивная критика 1
От: remark Россия http://www.1024cores.net/
Дата: 01.04.06 23:17
Оценка: 12 (1) +1
Здравствуйте, Евгений Охотников, Вы писали:

ЕО>Статья:

ЕО>SObjectizer: I Love This Game!
Автор(ы): Евгений Охотников
Дата: 31.03.2006
Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


ЕО>Авторы:

ЕО> Евгений Охотников

ЕО>Аннотация:

ЕО>Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


О достоинствах не буду — тебе они известны лучше Перейду сразу к тому, что мне лично кажется недостатками.
Хочу сразу сказать, что идея создания таких фреймворков, и этого в частности, мне нравится. Поэтому критику прошу рассматривать как конструктивную и имеющую цель приблизить наступление светлого будущего


1. Пугает идентификация событий и сообщений строкой:
so_subscribe( "evt_hello_time", "msg_hello_time" );


Даже, если копи-пастить эти строки, то ошибки возможны. Не говоря уже о сопровождаемости.
Ошибки могут отлавливаться только в ран-тайме, и только при запуске нужной ветви кода. Т.е. ошибка может быть в коде и быть обнаружена только через неопределённое время. В с++ и так много о чём приходится думать — неправильно записанный идентификатор сообщения — это не та проблема, о которой я хочу думать во время написания кода, и проводить время за отладкой для поиска.

Я имел дело с приложением, где запросы sql были размазаны по врему коду проекта. В нескольких таблицах имелось поле status. Плюс в программе было много разных лексемм, включающих слово status. Пока всё было протестированно и более-менее работало — нормально. Но когда встала например проблема удалить из одной таблицы поле status, то это было не легко. Приходилось искать в проекте слово status, но оно встречалось в запросах и в самом коде, причём в запросах оно могло иметь отношение у разным таблицам и быть записано в разном регистре, ну и в коде встречалось не редко...

У printf с его форматными строками проблемы растут оттуда же — есть переменная int в одном месте и форматная строка "%d" — вдругом. Потом кто-то меняет тип переменной на unsigned char — исход понятен. Или есть переменная CString и форматная строка "%s", потом кто-то меняет переменную на std::string — исход тоже понятен.

Вывод: в своём серьёзном проекте я бы не хотел видеть такие моменты — процент глупых ошибок связанных с этим при поддержке иногда доходит до 50% и больше. Самое обидное, что их мог бы отлавливать компилятор.
Что хотелось бы видеть: сообщения и события в виде типов, значений или ещё чего-то, что понимает компилятор. И чтобы при внесении изменений в одном месте компилятор сразу показывал возникшие проблемы в других местах.

Я недавно экспериментировал с наброском реализации publisher/subscriber. Там я сделал сообщения в виде типов:

struct TextChangedEvent : Event<TextChangedEvent>
{
    TextChangedEvent(const std::string& text, int id)
        : text_(text)
        , id_(id)
    {}

    std::string text_;
    int id_;
};


Тут же мы сразу привязываем данные к сообщению. А регистрацию в инфрастуктуре обеспечивает : Event<TextChangedEvent>.

Отправка:

send(TextChangedEvent(newText, myID));


Приём сообщения:

void process(const TextChangedEvent& e);


Эта же строчка обеспечивает подписку.
Всё полностью типобезопасно. Никаких cast'ов. На любые ошибки компилятор сразу ругается.
При этом удалось избежать централизации — т.е. например необходимости прописывать в базовом интерфейсе IEvent функций для обработки всех имеющихся типов сообщений.
Правда до логического завершения эту идею я так и не довёл тогда...




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Конструктивная критика 2
От: remark Россия http://www.1024cores.net/
Дата: 01.04.06 23:18
Оценка:
Здравствуйте, Евгений Охотников, Вы писали:

В продолжение предыдущего сообщения.

2. Всю документацию полностью не прочитал, но как я понял все сообщения в системе идут через единый коммутатор. В MPI (я так понял, ты с ним знаком) есть понятие коммутаторов, т.е. сущностей, которые принимают, маршрутизируют и отправляют сообщения. Для крупной системы имело бы смысл иметь несколько коммутаторов. Как с т.з. производительности, так и с т.з. логики работы. Коммутаторы могут иметь отношение к абсолютно разным частям системы — один к ui, другой к БД, другой к бизнес-логике, другой к инфраструктуре приложения. И зачем подсистеме ui иметь возможность принимать сообщения связанные с БД непонятно.

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

Отправка должнf выглядеть как:

send(message); // Отправка на глобальный коммутатор
send(message, subsystemNcommutator); // Отправка на коммутатор подсистемы N


Подписка объектов на коммутаторы:

subscribe(subsystemNCommutator);
subscribe(applicationFrameworkCommutator);




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 01.04.06 23:19
Оценка:
Здравствуйте, Евгений Охотников, Вы писали:

В продолжение предыдущего сообщения.

3. Состояния и агент являются монолитом. Агент находится сразу во всех состояниях по крайне мере в том смысле, что он должен содержать все данные, которые нужны всем его состояниям. Это плохо, т.к. (1) нелогично, (2) может привидить к ошибкам (когда агент обращается к своей переменной-члену, которая логически не имеет смысл в текущем состоянии агента, но физически она существует) и (3) может быть расточительно (данные одного состояния большие, но требуются очень редко).
Хотелось бы видеть состояния, как отдельные объекты. Например:

class Socket : public Agent<ActiveSocketState, PassiveSocketState>
{
    //...
};

class ActiveSocketState : State<ActiveSocketState>
{
public:
    void process(SocketDeactivateEvent&);
    void process(SocketPacketReceive&);

private:
    byte internalBuffer[65536];
};

class PassiveSocketState : State<PassiveSocketState>
{
public:
    void process(SocketActivateEvent&);
};


Переменная internalBuffer существует, занимает место в памяти, и доступна только в состоянии ActiveSocketState. В других состояниях к ней даже нельзя обратиться.
При небольшом извращении с языком, можно добиться, что бы такая конструкция являлась так же и описанием агента для SObjectizer, т.е. отпадает необходимость в SOL4_CLASS_START.
На данный момент при описании SOL4_CLASS_START присутствует дублирование и описание не так явно — ты писал в недостатках, что иногда забывают добавлять что-то в описание агента. При моём предложенном подходе, такие забывания сократились бы, т.к. не надо "при добавлении сюда, не забыть добавить туда".


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



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Конструктивная критика 4
От: remark Россия http://www.1024cores.net/
Дата: 02.04.06 00:03
Оценка: 12 (1)
Здравствуйте, Евгений Охотников, Вы писали:

В продолжение предыдущего сообщения.

4. Синхронные сообщения — всё-таки они нужны. Их отсутствие сужает область применения, если не в два раза, то по крайней мере на треть.
Это всё равно как заставить у всех функций использовать возвращаемый тип только void.

Иногда надо вернуть какой-то результат. Без этого теряется весь смысл. Т.е. подписчик на сообщение должен не только сделать что-то сам, но и сообщить что-то издателю. Самые простые примеры — есть контрол с текстом, и есть подписчики-валидаторы, которые при изменении текста должны его проверить и сообщить результат. Или какое-то важное сообщение (оповещение о завершении работы приложения).

Или взять например систему сообщений Windows — там всегда предусмотрена возможность вернуть результат обработки. У вас при использовании SObjectizer просто всегда есть возможность сделать обычный статический вызов при необходимости получить результат, а что если бы её не было? Или объект, у которого вызывается метод, надо перенести на другую машину? В случае, если имеется sync_send никаких доработок не понадобиться.

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

По поводу дедлоков — тут никуда не деться, тут они всегда были и остануться.


Фактически сейчас есть возможность отправлять синхронные сообщения:

struct SyncMessageParams
{
    int result;
    Event messageProcessed; // Событие, что сообщение обработано
    void wait(); // Ждать, пока сообщение не обработается
};

SyncMessageParams params;
async_send("msg", &params);
params.wait(); // Ждём пока сообщение будет обработано
if (params.result) ...;


Тока единственная проблема — только инфрастуктура может знать, что все подписчики обработали сообщение, и установить Event messageProcessed.
Поэтому нужна хотя бы минимальная поддержка со стороны инфрастуктуры — чтобы она установила Event после того как всё подписчики обработают сообщение. Необходимость такого действия можно определять например так: если параметры сообщения отнаследованы от некого SyncParams, то значит сообщение синхронное и надо установить этот Event.

В идеале, конечно, хотелось иметь более широкую поддержку синхронности.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Конструктивная критика 1
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 02.04.06 13:13
Оценка:
Здравствуйте, remark, Вы писали:

R>Хочу сразу сказать, что идея создания таких фреймворков, и этого в частности, мне нравится. Поэтому критику прошу рассматривать как конструктивную и имеющую цель приблизить наступление светлого будущего


Большое спасибо за проявленный интерес и потраченное время на написание этих сообщений. Будем теперь с ними разбираться.

R>1. Пугает идентификация событий и сообщений строкой:



Не тебя одного это пугает, по началу. Однако, практика показывает, что все не так страшно

R>
R>so_subscribe( "evt_hello_time", "msg_hello_time" );
R>


R>Вывод: в своём серьёзном проекте я бы не хотел видеть такие моменты — процент глупых ошибок связанных с этим при поддержке иногда доходит до 50% и больше. Самое обидное, что их мог бы отлавливать компилятор.

R>Что хотелось бы видеть: сообщения и события в виде типов, значений или ещё чего-то, что понимает компилятор. И чтобы при внесении изменений в одном месте компилятор сразу показывал возникшие проблемы в других местах.

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

Первоначально (еще в до-SObjectizer-овские времена) текстовые имена (в основном сообщений и состояний) нужны были для того, чтобы SObjectizer-приложением можно было управлять снаружи. Предполагалось, что с помошью подобного инструмента будут создаваться черные ящики, не имеющие средств диалога с пользователем. Но как-то же этими черными ящиками нужно было управлять. Причем хотелось бы, чтобы диалоговые программы для управления можно было писать не только на C++, но и на, к примеру, Visual Basic-е, Java или Python-е. Собственно, в прародителе SObjectizer-а (SCADA Objectizer) это даже было проделано. Был простенький тектовый протокол, названный SOP, который позволял отсылать в черный ящик сообщения, команды на смену состояния агента или запросы на получение состояния агента. Java-клиент с GUI интерфейсом подключался к черному ящику и мог с помощью SOP управлять черным ящиком.

Мне это показалось настолько удобно, что в SObjectizer я решил оставить использование текстовых имен для всех основных понятий (классов агентов, имен агентов, имен сообщений, состояний, событий). С одной стороны, это нужно для того, чтобы SObjectizer приложения могли обмениваться данными между собой (через SOP). С другой стороны, это нужно для того, чтобы SObjectizer RunTime мог отслеживать такие вещи, как наследование классов агентов и подписку и выдавать внятные сообщения об ошибках.

Кстати, это насколько удобно, что широко используется и сейчас. Например, для воздействия на SObjectizer-приложения во время отладки. Есть простенький инструментик, который позволяет отсылать по SOP команды в SObjectizer-приложения со стандартного ввода. Например, в отладке я использую такой SOP-файл (текстовый файл, содержащий SOP-команды) для выдачи команды на перезагрузку конфигурации компонента:
{send-msg
    {agent aag_3::smsc_map::default::a_router }
    {msg     msg_configure }
}
send
exit

Я просто запускаю:
so_send_stdin "какой-то IP" < reconfigure.sop

А вот с помощью этого ruby-скрипта при отладке имитируется поступление 5000 нужных мне сообщений:
1.upto( 5000 ) do |i|
    puts <<-EOF
{send-msg
    {agent    aag_3::smpp_smsc::bserver.trx::a_channel }
    {msg    msg_imit_delivery_receipt }
    {field    m_short_message
        {string-stream "id:#{i} sub:001 dlvrd:001 submit date:0508251625 done date:0508251625 stat:DELIVRD err:000 text:AAG3 test"} }
}
    EOF
    puts "send" if 0 == i % 10
end

puts "exit"

запускается это дело так:
ruby imit_delivery_receipt.rb | so_send_stdin "какой-то IP"

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

Так что было желание сохранить идентификацию основых понятий с помощью строк. Задача была в том, чтобы сократить количество строковых литералов в C++ коде и по максимому задействовать статическую типизацию. Где-то это удалось сделать. Например, при описании класса агента для SObjectizer строковых литералов нет (за исключением всего, что связано с описанием состояний). Имена классов, типов сообщений и имена событий должны быть корректными C++ идентификаторами. Например, попытка указать в SOL4_EVENT имя не существующего метода приведет к ошибке еще во время компиляции.

Но вот с именами сообщений и с моментом подписки все не так просто. Все дело в том, что в C++ нет никакой рефлексии, поэтому возникает вопрос о том, как, например, связать текстовое имя сообщения (которое необходимо для SOP) с C++ идентификатором типа сообщения. Можно было бы попробовать воспользоваться RTTI для получения из имени типа текстовое сообщение. Но, насколько я знаю, в разных компиляторах RTTI строит разные текстовые имена для одного и того же типа. А в SObjectizer требовалось, чтобы по SOP можно было связать несколько процессов, скомпилированных разными компиляторам. Поэтому RTTI не подошел. Далее можно было бы рассмотреть способ вроде такого:
struct msg_hello_time {
  static const std::string so_msg_name = "msg_hello_time";
  ...
};

Но заставлять пользователя подобные конструкции не очень хорошо, т.к. слишком много писанины. Ну и не все компиляторы в свое время поддерживали описание static const в определении класса/структуры. Получалось, что попытка как-то связать имя типа с именем сообщения в C++ приведет к использованию макросов. Макросов же в SObjectizer и так не мало. Лишние без необходимости вводить не хотелось.

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

С идентификацией имен событий вообще плохо, т.к. событие -- это метод. А с идентификатором имени метода в C++ вообще не много чего можно сделать.

Так что получалось, что код мог выглядеть как-то так:
so_subscribe( SO4_EVENT_NAME( a_hello_t, evt_hello_time ), SO4_MSG_NAME( msg_hello_time ) );

но лично мне такая запись не нравится.

Далее, так ли плохи строковые идентификаторы? Вообще-то говоря, они дают возможность управлять подпиской в run-time. Если бы я написал в C++ коде что-то вроде:
subscribe< msg_hello_time >( &a_hello_t::evt_hello_time );

то намертво бы закрепил связь между сообщением msg_hello_time и evt_hello_time. Но как связать evt_hello_time с другим сообщением в run-time? Подобная статическая связанность была в последней версии SCADA Objectizer и являлась чуть ли не самым большим недостатком, т.к. на практике требовалось динамически менять подписку, причем имя сообщения (а иногда и события) могло стать известно только в run-time.

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

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

Теперь о страхах и вероятности все запортить связав не то не с тем. Очевидно, что SObjectizer позволяет наломать дров. Но в SObjectizer предпринимаются некоторые шаги для повышения безопасности. Во-первых, использование макроса SO4_EVENT_STC(evt_name, msg_name) указывает SObjectizer, что evt_name будет получать только сообщения типа msg_name. И эта информация позволяет в so_subscribe проверить типа сообщения на которое подписывается сообщение. И, если у сообщения другой тип, то подписка не выполняется. Однако, в момент отсылки сообщения SObjectizer не в состоянии проверить тип указателя, передаваемый в send_msg(). Поэтому, если пользователь отослал агенту сообщение не того типа, то SObjectizer помочь здесь не сможет. Ну это обычная ситуация в C++ приложениях при передаче информации через void*. Если же попробовать отказаться от void*, то тогда агент лишается возможности подписать свое событие на несколько разнотипых сообщений. А иногда это нужно. Например, агенту-коммуникатору. Или прикладному агенту, которому не столь важны данные в сообщении, сколько сам факт наличия сообщения.

Во-вторых, при подписке события SObjectizer проверяет наличие в словаре имен событий и сообщений. Поэтому попытка пописать несуществующее сообщение или несуществующее событие завершается возникновением ошибки. А поскольку в большинстве случаев подписка выполняется в одном централизованном методе so_on_subscription(), то ошибки подписки сразу становятся заметны.

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

Так же нет проблем с сопровождением строковых литералов. Этому способствует использование нотации: префикс evt_ для имен событий и msg_ для имен сообщений. Поэтому такие распространенные имена, как status в качестве имен событий/сообщений практически не встречаются. Если же возникает необходимость сменить имя события, например, с evt_hello_time на evt_yet_another_hello, то в коде все равно следует искать подстроку evt_hello_time, а затем уже на месте смотреть, нужно ли это вхождение или следует искать дальше. И здесь уже без разницы, является ли найденная подстрока частью идентификатора или строкового литерала. То, что компилятор не сможет проверить корректность имен событий/сообщений -- это не приятно. Но выручают проверки, выполняемые самим SObjectizer. Так что на практике проблем с сопровождением строковых литералов не было.

R>Приём сообщения:


R>
R>void process(const TextChangedEvent& e);
R>


R>Эта же строчка обеспечивает подписку.


Кстати, не расскажешь, как именно декларация функции/метода может обеспечить автоматическую подписку?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Конструктивная критика 2
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 02.04.06 13:26
Оценка:
Здравствуйте, remark, Вы писали:

R>2. Всю документацию полностью не прочитал, но как я понял все сообщения в системе идут через единый коммутатор. В MPI (я так понял, ты с ним знаком) есть понятие коммутаторов, т.е. сущностей, которые принимают, маршрутизируют и отправляют сообщения. Для крупной системы имело бы смысл иметь несколько коммутаторов. Как с т.з. производительности, так и с т.з. логики работы. Коммутаторы могут иметь отношение к абсолютно разным частям системы — один к ui, другой к БД, другой к бизнес-логике, другой к инфраструктуре приложения. И зачем подсистеме ui иметь возможность принимать сообщения связанные с БД непонятно.


Вообще-то агент-коммуникатор обслуживает только сообщения глобальных агентов. Он занимается их маршаллингом/демаршалингом.
В приложении может быть только один SObjectizer Run-Time, который занимается диспетчеризацией всех сообщений. Може ты его имел в виду под единым коммутатором?

Вообще-то это моя ошибка, допущенная во время проектирования и реализации SObjectizer: что Run-Time может быть только один. В последствии возникало несколько задач, где хотелось бы иметь возможности запустить отдельный SObjectizer Run-Time. Во всех случаях это были библиотеки, которые скрывали от пользователей факт использования внутри себя SObjectizer-а. Библиотека сама запускала SObjectizer, использовала его (в основном для коммуникации с каким-нибудь SObjectizer-приложением) и останавливала. Потенциально, в одном приложении нельзя было использовать несколько подобных библиотек. Но на практике эта опасность пока, к счастью, не воплотилась.

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

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 02.04.06 13:50
Оценка:
Здравствуйте, remark, Вы писали:

R>3. Состояния и агент являются монолитом. Агент находится сразу во всех состояниях по крайне мере в том смысле, что он должен содержать все данные, которые нужны всем его состояниям. Это плохо, т.к. (1) нелогично, (2) может привидить к ошибкам (когда агент обращается к своей переменной-члену, которая логически не имеет смысл в текущем состоянии агента, но физически она существует) и (3) может быть расточительно (данные одного состояния большие, но требуются очень редко).


Вот с этим пунктом не согласен категорически. Особенно с пунктами (1) /видимо у меня логика другая / и (2).

Агент -- это прежде всего объект. Состояние определяет не то, из чего агент будет состоять, а то, как агент будет реагировать на внешние события. И, опять же из практики, агенту часто нужны все его составляюшие, чтобы корректно работать в очередном состоянии. Например, агент может отвечать за транспортировку транзакций на удаленную сторону. В состояние st_connected (когда есть соединение с удаленной стороной) агент берет транзакции из своей внутренней очереди и отправляет их в канал. Когда связи нет, состояние st_disconnected, агент может ставить новые транзакции в очередь (если там есть место) в надежде отослать их в канал при восстановлении соединения. А может и переодически пересканировать список транзакций и вычеркивать самые старые.

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

Если же есть проблемы с потреблением ресурсов (что, вообще-то говоря не так уж и вероятно), то при смене состояния можно очищать или создавать ресурсы заново (благо в SObjectizer можно вешать обработчики на вход в состояние и выход из состояния). При этом время на создание/удаление ресурсов ты будешь тратить в случаях, когда это действительно необходимо.

В подходе, предложенном тобой пересоздание ресурсов происходит всегда при смене состояния. Даже тогда, когда в этом нет необходимости.

R>На данный момент при описании SOL4_CLASS_START присутствует дублирование и описание не так явно — ты писал в недостатках, что иногда забывают добавлять что-то в описание агента. При моём предложенном подходе, такие забывания сократились бы, т.к. не надо "при добавлении сюда, не забыть добавить туда".


Ты забываешь один момент: в C++ синтаксисе не достаточно средств для того, чтобы выразить все, что необходимо SObjectizer. В частности, привязывание событий к состояниям и наследование событий/состояний из разных классов агентов. Поэтому что-то вроде SOL4_CLASS_START все равно потребовалось бы. И проблема дублирования описаний и там и там все равно бы осталась. Нет, конечно, можно что-нибудь в духе метапрограммирования на шаблонах замутить. Но мои попытки придумать что-либо подобное приводило к слишком уж сложным и неудобным в использовании наворотам. Причем именно с точки зрения пользователя SObjectizer получалось не очень удобно и декларативно, описания в SOL4_CLASS_* выглядели по сравнению с шаблонами гораздо проще, понятнее и декларативнее.

Единственный реальный выход из этого я вижу в использовании специализированного DSL, из описания на котором будут автоматически генерироваться, как минимум:
— фрагменты C++ кода для размещения в декларации класса агента;
— все содержимое описания класса агента для SObjectizer (все, что между макросами SOL4_CLASS_START/SOL4_CLASS_FINISH).
Возможно, что из такого описания можно будет генерировать метод so_on_subscription и заглушки для методов-событий.
В качестве проверки такой кодогенерации был затеян проект RuCodeGen
Автор: eao197
Дата: 16.11.05
. Пока нет точного определения самого DSL (только приблизительные наметки).

R>Так же возможно (не знаю, насколько это реально) повторное использование состояний. Т.е. Агенты и состояния становятся перпендикулярными, и для агента можно просто набрать множество уже готовых состояний — и вот новый агент.


Для этого можно использовать обычное множественное наследование, имхо.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Конструктивная критика 4
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 02.04.06 14:33
Оценка:
Здравствуйте, remark, Вы писали:

R>4. Синхронные сообщения — всё-таки они нужны. Их отсутствие сужает область применения, если не в два раза, то по крайней мере на треть.


Дык я же не спорю (почти). Не понятно только, как и какой ценой. Пока как-то получается, что цена за добавление синхронности слишком высокая оказывается.

R>Иногда надо вернуть какой-то результат. Без этого теряется весь смысл. Т.е. подписчик на сообщение должен не только сделать что-то сам, но и сообщить что-то издателю.


Сейчас это делается отсылкой ответного сообщения.

R>Самые простые примеры — есть контрол с текстом, и есть подписчики-валидаторы, которые при изменении текста должны его проверить и сообщить результат.


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

R>Или какое-то важное сообщение (оповещение о завершении работы приложения).


А в чем проблема в использовании для этого дела асинхронного сообщения?

R>Или взять например систему сообщений Windows — там всегда предусмотрена возможность вернуть результат обработки.


Насколько я помню, использование SendMessage в Win32 для взаимодействия нескольких потоков или приложений -- это не самый удобный и рекомендуемый вариант работы.

R>У вас при использовании SObjectizer просто всегда есть возможность сделать обычный статический вызов при необходимости получить результат, а что если бы её не было? Или объект, у которого вызывается метод, надо перенести на другую машину? В случае, если имеется sync_send никаких доработок не понадобиться.


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

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

R>Проблемы с потоками вполне можно решить: отправитель сообщения всегда работает в своём потоке, а инфрастуктура отдаёт сообщение диспетчеру и ждёт ответа, далее возвращает ответ вызвавшему потоку. При этом с т.з. кто в каком потоке работает выглядит всё точно так же как при асинхронном сообщении.


Самая большая проблема с потоками вот в чем. Метод send_msg ставит заявку в очередь соответствующей рабочей нити диспетчера (по этой причине в SObjectizer нет очередей сообщений в принципе, есть только очереди уже отдиспетчеризированных заявок). Нить диспетчера в цикле выбирает заявки из своей очереди и вызвает метод-событие у агента. Если агент в событии отсылает синхронное сообщение, которое приходит на ту же самую нить диспетчера, то окажется, что нить заблокированна самой собой. Здесь нужен какой-то способ, чтобы войти повторно в цикл выборки сообщений из собственной очереди и продолжать обработку заявок.

Кроме того, что я не придумал простого способа подобных повторных входов/выходов (а над сложным думать было некогда ), есть еще и другие белые пятна. Например, предположим, что есть агент A, к которому стоят заявки a2, b1, c0 (цифра -- это приоритет). Во время обработки a2 агент A синхронно обращается к агенту B, но агент B должен обработать это обращение на той же нити. Получится, что в очереди рабочей нити стоят заявки b1(A), c0(A) и d0(B) /в скобках показан агент, которому принадлежит событие/. Когда рабочая нить повторно начнет выборку событий из своей очереди окажется, что события b1(A) и c0(A) извлекать и обрабатывать нельзя, т.к. они менее приоритетны события a2 и не могут быть обработаны до завершения обработки a2. Такие нюансы, во-первых, усложняют систему диспетчеризации, во-вторых, увеличивают накладные расходы на нее (в особенности на поиск и преодоление дедлоков). И, в-третьих, как мне кажется, способны только усложнить проектирование приложений в SObjectizer.

R>По поводу дедлоков — тут никуда не деться, тут они всегда были и остануться.


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


R>Фактически сейчас есть возможность отправлять синхронные сообщения:


R>
R>struct SyncMessageParams
R>{
R>    int result;
R>    Event messageProcessed; // Событие, что сообщение обработано
R>    void wait(); // Ждать, пока сообщение не обработается
R>};

R>SyncMessageParams params;
R>async_send("msg", &params);
R>params.wait(); // Ждём пока сообщение будет обработано
R>if (params.result) ...;
R>


Это не правильный код
Сообщения должны быть динамически созданными объектами, удалением которых занимается сам SObjectizer.

R>Тока единственная проблема — только инфрастуктура может знать, что все подписчики обработали сообщение, и установить Event messageProcessed.

R>Поэтому нужна хотя бы минимальная поддержка со стороны инфрастуктуры — чтобы она установила Event после того как всё подписчики обработают сообщение. Необходимость такого действия можно определять например так: если параметры сообщения отнаследованы от некого SyncParams, то значит сообщение синхронное и надо установить этот Event.

Настораживает меня фраза "все подписчики обработали сообщение". Имхо, если речь заходит о синхронном взаимодействии. то оно не может быть широковещательным, а только целенаправленным (адресным).

Мне бы виделось использование синхронности в каком-то таком виде:
// Инициатор синхронного сообщения.
so_4::rt::sync_response_t< msg_response > resp;
if( !so_4::api::send_msg_safely( some_agent, "msg_do_this", request, receiver_name, resp ) )
  {
    // Сообщение отправлено. Можно ждать результата.
    ...
    if( !resp.wait() )
      // Результат получен. Обрабатываем его.
      ...
    else // Произошла ошибка получения результата.
      ...
  }
else // Произошла ошибка отсылки синхронного сообщения.
  ...

// Код обработчика синхронного сообщения.
void
evt_do_this(
  so_4::rt::event_data_t & event_data,
  const msg_do_this & cmd )
  {
    // Обработка.
    ...
    // Отсылка ответа.
    event_data.reply( new msg_response( ... ) );
    ...
  }


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Конструктивная критика 1
От: remark Россия http://www.1024cores.net/
Дата: 02.04.06 21:18
Оценка:
Здравствуйте, eao197, Вы писали:

R>>1. Пугает идентификация событий и сообщений строкой:


E>Не тебя одного это пугает, по началу. Однако, практика показывает, что все не так страшно


E>Давай я попробую рассказать, откуда пошло использование текстовых имен, в чем проблемы привязки к именам типов для статического контроля, некоторые достоинства текстовых имен.



В целом я понял. Да, если будет типизация, то не будет связи с внешними системами, и не будет возможности отсылать сообщения в систему вручную.
То, что ты говоришь, тоже имеет смысл.


E>
E>1.upto( 5000 ) do |i|
E>    puts <<-EOF
E>{send-msg
E>    {agent    aag_3::smpp_smsc::bserver.trx::a_channel }
E>    {msg    msg_imit_delivery_receipt }
E>    {field    m_short_message
E>        {string-stream "id:#{i} sub:001 dlvrd:001 submit date:0508251625 done date:0508251625 stat:DELIVRD err:000 text:AAG3 test"} }
E>}
E>    EOF
E>    puts "send" if 0 == i % 10
E>end

E>puts "exit"
E>



А вот тут можно поподробнее. Выделенная строка это что? Это кто будет парсить? Или это никто не будет парсить, это и есть сообщение в том виде, в котором оно попадёт в метод-обработчик события?

Сюда же вопрос — если я извне посылаю сообщение, то строковый идентификатор соообщения указать не проблема, но как создать объект с параметрами?
Объект создаёт рантайм SO на основе этого:
SOL4_MSG_START(msg_alarm, msg_alarm)
  SOL4_MSG_FIELD(m_sensor_name)
  SOL4_MSG_FIELD(m_current_value)
  SOL4_MSG_FIELD(m_max)
SOL4_MSG_FINISH()

?

Если это так, то это очень грамотно




E>Подобная статическая связанность была в последней версии SCADA Objectizer и являлась чуть ли не самым большим недостатком, т.к. на практике требовалось динамически менять подписку, причем имя сообщения (а иногда и события) могло стать известно только в run-time.


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



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


Такое подозрение у меня уже возникло
А как насчёт SmallTalk? Ваша система, по-моему, достаточно похожа на работу объектов в SmallTalk? Только там асинхронности не хватает.



E>Или прикладному агенту, которому не столь важны данные в сообщении, сколько сам факт наличия сообщения.



А как насчёт наследования строковых идентификаторов?
У меня была такая идея:

struct SMSStateChange: Event {};
struct SMSReceivedEvent: SMSStateChange{};
struct SMSSavedToDBEvent: SMSStateChange{};


Соответственно кто-то может подписаться на:

void subscrive(SMSSavedToDBEvent& e);


А кто-то просто:

void subscrive(SMSStateChange& e);


Я так понимаю. что когда ты говоришь "важен сам факт наличия сообщения, а данные не важны", то фактически это означет, что важна реакция на некий базовый тип сообщения, а не на производный.





R>>Приём сообщения:


R>>
R>>void process(const TextChangedEvent& e);
R>>


R>>Эта же строчка обеспечивает подписку.


E>Кстати, не расскажешь, как именно декларация функции/метода может обеспечить автоматическую подписку?


У меня на шаблонах было. Т.е. генерация кода во время компиляции — я с помощью SFINAE проверяю наличие данного метода. Допустим надо сгенерировать код для реакции объекта класса SomeClass на событие SomeEvent. Я проверял наличие метода:
void SomeClass::process(SomeEvent&);




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Конструктивная критика 2
От: remark Россия http://www.1024cores.net/
Дата: 02.04.06 21:20
Оценка:
Здравствуйте, eao197, Вы писали:

E>Наличие же единственного SObjectizer Run-Time, с другой стороны, сильно упрощает использование SObjectizer. Не болит голова о том, в каком Run-Time агент зарегистрирован, в какой Run-Time нужно отсылать сообщения. И нет вопросов о том, что делать, если агент должен одновременно входить в несколько Run-Time.



В MPI не понятия вхождения агента в коммутатор. Да собственно нужно ли оно? Просто при отсылке сообщения можно указать идентификатор коммутатора.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 02.04.06 22:25
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>3. Состояния и агент являются монолитом. Агент находится сразу во всех состояниях по крайне мере в том смысле, что он должен содержать все данные, которые нужны всем его состояниям. Это плохо, т.к. (1) нелогично, (2) может привидить к ошибкам (когда агент обращается к своей переменной-члену, которая логически не имеет смысл в текущем состоянии агента, но физически она существует) и (3) может быть расточительно (данные одного состояния большие, но требуются очень редко).


E>Вот с этим пунктом не согласен категорически. Особенно с пунктами (1) /видимо у меня логика другая / и (2).


E>Агент -- это прежде всего объект. Состояние определяет не то, из чего агент будет состоять, а то, как агент будет реагировать на внешние события. И, опять же из практики, агенту часто нужны все его составляюшие, чтобы корректно работать в очередном состоянии. Например, агент может отвечать за транспортировку транзакций на удаленную сторону. В состояние st_connected (когда есть соединение с удаленной стороной) агент берет транзакции из своей внутренней очереди и отправляет их в канал. Когда связи нет, состояние st_disconnected, агент может ставить новые транзакции в очередь (если там есть место) в надежде отослать их в канал при восстановлении соединения. А может и переодически пересканировать список транзакций и вычеркивать самые старые.


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



Состояние, конечно, в первую очередь определяет поведение. Но для реализации поведения данного состояния могут понадобиться данные.
В твоём примере очередь должна относиться не к состоянию, а к самому объекту. А вот канал относится уже исключительно к состоянию st_connected.
А что будет, если я в состоянии st_disconnected вызову какой-то метод канала — ничего хорошего. И это логическая ошибка. Т.е. прграммист скорее всего не хотел это написать — не хотел, что бы в состоянии st_disconnected происходили какие-либо вызовы канала.
Задача хорошего дизайна — отлавливать логические ошибки на этапе компиляции.
А если состояние — это объект, то мы как раз уменьшаем область видимости данных только до той, где они реально нужны и могут использоваться.
Ну как, например, когда автоматическую переменную мы помещаем в блок {}, если кто-то попытается обратиться к этой переменной за пределами блока, то компилятор сообщит об ошибке.
С состояниями, мне кажется, имеет место такая же ситуация.



E>Если же есть проблемы с потреблением ресурсов (что, вообще-то говоря не так уж и вероятно), то при смене состояния можно очищать или создавать ресурсы заново (благо в SObjectizer можно вешать обработчики на вход в состояние и выход из состояния). При этом время на создание/удаление ресурсов ты будешь тратить в случаях, когда это действительно необходимо.


E>В подходе, предложенном тобой пересоздание ресурсов происходит всегда при смене состояния. Даже тогда, когда в этом нет необходимости.


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





E>Единственный реальный выход из этого я вижу в использовании специализированного DSL, из описания на котором будут автоматически генерироваться, как минимум:

E>- фрагменты C++ кода для размещения в декларации класса агента;
E>- все содержимое описания класса агента для SObjectizer (все, что между макросами SOL4_CLASS_START/SOL4_CLASS_FINISH).
E>Возможно, что из такого описания можно будет генерировать метод so_on_subscription и заглушки для методов-событий.
E>В качестве проверки такой кодогенерации был затеян проект RuCodeGen
Автор: eao197
Дата: 16.11.05
. Пока нет точного определения самого DSL (только приблизительные наметки).



"А вот это попробуйте"
Такая мысль у меня тоже возникла при виде всех этих макросов в коде



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: Конструктивная критика 4
От: remark Россия http://www.1024cores.net/
Дата: 02.04.06 22:34
Оценка:
Здравствуйте, eao197, Вы писали:


R>>Самые простые примеры — есть контрол с текстом, и есть подписчики-валидаторы, которые при изменении текста должны его проверить и сообщить результат.


E>Кстати, не удачный пример. Взаимодействие посредством сообщений слишком дорогая операция, чтобы делать с помощью SObjectizer-а валидацию текста в контроле. Это как раз отличный пример того, для чего SObjectizer не имеет смысла использовать.


Я имел в виду не пример применения SObjectizer, а пример, где не обойтись без синхронности.



R>>Или какое-то важное сообщение (оповещение о завершении работы приложения).


E>А в чем проблема в использовании для этого дела асинхронного сообщения?


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





E>Кроме того, что я не придумал простого способа подобных повторных входов/выходов (а над сложным думать было некогда ), есть еще и другие белые пятна. Например, предположим, что есть агент A, к которому стоят заявки a2, b1, c0 (цифра -- это приоритет). Во время обработки a2 агент A синхронно обращается к агенту B, но агент B должен обработать это обращение на той же нити. Получится, что в очереди рабочей нити стоят заявки b1(A), c0(A) и d0(B) /в скобках показан агент, которому принадлежит событие/. Когда рабочая нить повторно начнет выборку событий из своей очереди окажется, что события b1(A) и c0(A) извлекать и обрабатывать нельзя, т.к. они менее приоритетны события a2 и не могут быть обработаны до завершения обработки a2. Такие нюансы, во-первых, усложняют систему диспетчеризации, во-вторых, увеличивают накладные расходы на нее (в особенности на поиск и преодоление дедлоков). И, в-третьих, как мне кажется, способны только усложнить проектирование приложений в SObjectizer.


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





E>Настораживает меня фраза "все подписчики обработали сообщение". Имхо, если речь заходит о синхронном взаимодействии. то оно не может быть широковещательным, а только целенаправленным (адресным).


Почему? Опять же пример с валидацией текста.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Конструктивная критика 1
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.04.06 06:44
Оценка:
Здравствуйте, remark, Вы писали:

R>В целом я понял. Да, если будет типизация, то не будет связи с внешними системами, и не будет возможности отсылать сообщения в систему вручную.


Вот именно.

E>>
E>>1.upto( 5000 ) do |i|
E>>    puts <<-EOF
E>>{send-msg
E>>    {agent    aag_3::smpp_smsc::bserver.trx::a_channel }
E>>    {msg    msg_imit_delivery_receipt }
E>>    {field    m_short_message
E>>        {string-stream "id:#{i} sub:001 dlvrd:001 submit date:0508251625 done date:0508251625 stat:DELIVRD err:000 text:AAG3 test"} }
E>>}
E>>    EOF
E>>    puts "send" if 0 == i % 10
E>>end

E>>puts "exit"
E>>


R>А вот тут можно поподробнее. Выделенная строка это что? Это кто будет парсить? Или это никто не будет парсить, это и есть сообщение в том виде, в котором оно попадёт в метод-обработчик события?


Тег {string-stream} — это часть текстового представления SOP-а, его парсит so_send_stdin. А значение в ковычках -- это значение для поля m_short_message. Именно таким оно и придет во внутрь приложения. Для того, чтобы это дело работало, атрибут msg_imit_delivery_receipt::m_short_message должен иметь в C++ программе тип std::string или char[].

R>Сюда же вопрос — если я извне посылаю сообщение, то строковый идентификатор соообщения указать не проблема, но как создать объект с параметрами?

R>Объект создаёт рантайм SO на основе этого:
R>
R>SOL4_MSG_START(msg_alarm, msg_alarm)
R>  SOL4_MSG_FIELD(m_sensor_name)
R>  SOL4_MSG_FIELD(m_current_value)
R>  SOL4_MSG_FIELD(m_max)
R>SOL4_MSG_FINISH()
R>

R>?

R>Если это так, то это очень грамотно


Это так. Для каждого сообщения задекларированного через SOL4_MSG_START/FINISH рантайм умеет создавать динамически объекты по необходимости (при получении этого сообщения по SOP). Отсюда и ограничения: сообщение в SObjectizer должно иметь конструктор по-умолчанию. В динамически созданный объект сообщения SObjectizer способен помещать значения полей, перечисленных в макросах SOL4_MSG_FIELD. Собственно, эти макросы и нужны для того, чтобы сделать сообщение доступным через SOP.

E>>Подобная статическая связанность была в последней версии SCADA Objectizer и являлась чуть ли не самым большим недостатком, т.к. на практике требовалось динамически менять подписку, причем имя сообщения (а иногда и события) могло стать известно только в run-time.


R>Да, тут со строками действительно проще.

R>Хотя я не очень понимаю, как агент может реагировать на сообщения/события, для которых не написан код во время разработки.

Код должен быть написан, это понятно. Но есть несколько моментов:
* агент-коммуникатор способен работать с любыми сообщениями для маршаллинга/демаршаллинга, используя для этого информацию из системного словаря SObjectizer;
* некий агент способен обрабатывать разнотипные сообщения, если ему не важно содержимое этих сообщений, а важен сам факт их наличия;
* в некоторых случаях агент способен обрабатывать сообщения, производные от некоторого базового типа (обычный полиморфизм и работа через базовый интерфейс).

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

R>А как насчёт SmallTalk? Ваша система, по-моему, достаточно похожа на работу объектов в SmallTalk? Только там асинхронности не хватает.


Со SmallTalk-ом я, к сожалению, знаком очень поверхностно, ничего не писал на нем.
Но похожая схема не только в SmallTalk, но и в Ruby.

R>А как насчёт наследования строковых идентификаторов?

R>У меня была такая идея:
<...код поскипан...>
R>Я так понимаю. что когда ты говоришь "важен сам факт наличия сообщения, а данные не важны", то фактически это означет, что важна реакция на некий базовый тип сообщения, а не на производный.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Конструктивная критика 2
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.04.06 07:16
Оценка:
Здравствуйте, remark, Вы писали:

E>>Наличие же единственного SObjectizer Run-Time, с другой стороны, сильно упрощает использование SObjectizer. Не болит голова о том, в каком Run-Time агент зарегистрирован, в какой Run-Time нужно отсылать сообщения. И нет вопросов о том, что делать, если агент должен одновременно входить в несколько Run-Time.


R>В MPI не понятия вхождения агента в коммутатор. Да собственно нужно ли оно? Просто при отсылке сообщения можно указать идентификатор коммутатора.


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

Итак, кто-то вызывает send_msg. SObjectizer блокирует свой системный словарь в режиме read-only, проверяет наличие сообщения в системе. Если сообщение есть, то создается экземпляр заявки. После этого системный словарь разблокируется, а заявка передается диспетчеру, который помещает ее в нужную очередь.

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

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.04.06 07:55
Оценка:
Здравствуйте, remark, Вы писали:

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

R>В твоём примере очередь должна относиться не к состоянию, а к самому объекту. А вот канал относится уже исключительно к состоянию st_connected.
R>А что будет, если я в состоянии st_disconnected вызову какой-то метод канала — ничего хорошего. И это логическая ошибка. Т.е. прграммист скорее всего не хотел это написать — не хотел, что бы в состоянии st_disconnected происходили какие-либо вызовы канала.

Во-первых, обращения к каналу в состоянии st_disconnected, скорее всего, все равно потребуются. Хотя бы для инициирования переподключения
Во-вторых, в SObjectizer я бы выделил канал в другого агента И так на самом деле и происходит. В составе SObjectizer есть транспортные агенты (для работы с SOP и с RAW-каналами (a_cln_channel_t, a_raw_cln_channel_t)), которые в своем состояние st_disconnected дергают свой атрибут-канал для восстановления подключения. Когда подключение восстанавливается, они отсылают сообщение об этом. Если агент, занимающийся обработкой транзкций заинтересован в этом сообщении, то он подписывается на это сообщение.

Т.е. я не могу припомнить ситуаций, когда бы внутри объектов-агентов, какие-то атрибуты были бы восстребованы только в одном состоянии.

E>>В качестве проверки такой кодогенерации был затеян проект RuCodeGen
Автор: eao197
Дата: 16.11.05
. Пока нет точного определения самого DSL (только приблизительные наметки).


R>"А вот это попробуйте"

R>Такая мысль у меня тоже возникла при виде всех этих макросов в коде

Я когда стал обдумывать DSL для описания агентов еще задумался о том, чтобы портировать SObjectizer в Ruby
Так что сейчас думаю, как бы этот DSL использовать одновременно и для Ruby-классов и для C++. Пока получается что-то вроде:
class SomeAgent < So4::Rt::Agent
  # Событие, которое получает event_data. Приоритет и подписка определяется в динамике.
  so4_event :evt_1 do |event_data|
    # Код обработчика события.
    ...
  end

  # Событие, которое не получает вообще никаких аргументов.
  so4_event :evt_2 do ... end

  # Событие, которое получает и event_data и сообщение.
  # Сразу же определяется инцидент и приоритет.
  so4_event :evt_3,
    :msg => Start, :owner => :starter, # Инцидентом является сообщение starter.Start.
    :priority => 1 do |event_data, msg|
    # Код обработчика события...
  end

  # Распределение событий по состояниям.
  so4_state :st_initial,
    :events => [ :evt_1 ]

  so4_state :st_normal,
    :events => [ :evt_2, evt_3 ],
    :on_enter => :on_enter_st_shutdown # Для Ruby здесь даже можно блок кода определить.
end


В общем, есть впечатление, что в Ruby SObjectizer использовать даже удобнее было бы

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Конструктивная критика 4
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.04.06 08:04
Оценка:
Здравствуйте, remark, Вы писали:

R>Забавно. Типа "ну вы вообще конечно начинайте готовиться к завершению программы, но процесс всё равно умрёт неожиданно"



В реальности у нас есть проектик so_sysconf (который позволяет формировать SObjectizer-приложение из кубиков-DLL как из конструктора Lego). Там есть такая задача. Решается она следующим образом -- если кому-то нужно выполнить какие-то действия перед завершением приложения, то этот агент регистрируется у sysconf-а. При начале shutdown-а всем таким агентам sysconf отсылает специальное сообщение. Агент, получив его, выполняет необходимые ему действия, а по их завершению дерегистрируется у sysconf-а. Когда sysconf видит, что все агента дерегистрировались, он выполняет реальный shutdown. Здесь есть еще одно преимущество -- агенты могут выполнять свой shutdown параллельно.

R>Я об этом и говорю, что синхронный lock-подход на критический секциях по определению будет связан с дедлоками. Эту проблему не решить вообще. Все кто занимается синхронным взаимодействием об этом прекрасно осведомлены.


Так вот дело в том, что если SObjectizer не будет такие дедлоки диагностировать и преодолевать, то работа с их наличием будет не веселой. Они же будут эпизодическими и часто их повторение в тестовых условиях будет крайне затруднено.

А если заставить SObjectizer такие дедлоки диагностировать, то затраты на определение дедлока могут быть слишком высокими.

Так мне пока кажется.

E>>Настораживает меня фраза "все подписчики обработали сообщение". Имхо, если речь заходит о синхронном взаимодействии. то оно не может быть широковещательным, а только целенаправленным (адресным).


R>Почему? Опять же пример с валидацией текста.


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: RealFduch  
Дата: 03.04.06 16:00
Оценка: :)
Здравствуйте, Евгений Охотников, Вы писали:

ЕО>Статья:

ЕО>SObjectizer: I Love This Game!
Автор(ы): Евгений Охотников
Дата: 31.03.2006
Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


Это ппц... 2 дня назад придумал ЭТО. Ну почти это... Уже код льётся рекой и тут натыкаюсь на статью.... даже не знаю что теперь делать. Наверное найду что-то меня не устраивающее и пойду писать дальше
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.04.06 17:49
Оценка:
Здравствуйте, RealFduch, Вы писали:

RF>Это ппц... 2 дня назад придумал ЭТО. Ну почти это... Уже код льётся рекой и тут натыкаюсь на статью.... даже не знаю что теперь делать. Наверное найду что-то меня не устраивающее и пойду писать дальше




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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Конструктивная критика 1
От: remark Россия http://www.1024cores.net/
Дата: 03.04.06 21:00
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>В целом я понял. Да, если будет типизация, то не будет связи с внешними системами, и не будет возможности отсылать сообщения в систему вручную.


E>Вот именно.



E>Это так. Для каждого сообщения задекларированного через SOL4_MSG_START/FINISH рантайм умеет создавать динамически объекты по необходимости (при получении этого сообщения по SOP). Отсюда и ограничения: сообщение в SObjectizer должно иметь конструктор по-умолчанию. В динамически созданный объект сообщения SObjectizer способен помещать значения полей, перечисленных в макросах SOL4_MSG_FIELD. Собственно, эти макросы и нужны для того, чтобы сделать сообщение доступным через SOP.



Я SOL4_MSG_START сразу не заметил.
Тогда у меня 2 вопроса:
1. Зачем описывать сам класс сообщения отдельно. Можно обойтись только SOL4_MSG_START, который заодно будет создавать и описание класса. Это, конечно, немного "урезает" возможности сообщений, т.е. в них будет нельзя добавить своего кода. Но в некоторых местах дополнительные ограничения идут только на пользу.
Иначе, во-первых, дублирование со всеми вытекающими.
Во-вторых, не очень прозрачные возможности, типа добавить какой-то член в класс сообщения, но не описать его в SOL4_MSG_START.

2. Отпадают все плюсы использования текстовых идентификаторов для сообщений, о которых ты писал! Если рантайм может преобразовывать сообщения в/из текстового представления, то в программе можно использовать исключительно типы в качестве идентификаторов сообщений. Но при этом не теряется возможность обмена с внешними подсистемами и "ручного" ввода сообщений внутрь системы.







R>>А как насчёт наследования строковых идентификаторов?

R>>У меня была такая идея:
E><...код поскипан...>
R>>Я так понимаю. что когда ты говоришь "важен сам факт наличия сообщения, а данные не важны", то фактически это означет, что важна реакция на некий базовый тип сообщения, а не на производный.

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


Да, только я имею в виду, что при варианте с наследованием классов сообщений и не надо будет таких извращений:

E>* агент-коммуникатор способен работать с любыми сообщениями для маршаллинга/демаршаллинга, используя для этого информацию из системного словаря SObjectizer;


Подписываемся на базовый класс сообщений.
При этом как сам базовый класс, так и ран-тайм предоставляет некоторые базовые функции для работы с этим сообщением.

E>* некий агент способен обрабатывать разнотипные сообщения, если ему не важно содержимое этих сообщений, а важен сам факт их наличия;


Это я не очень понял что значит. Но возможно тоже можно решить с помощью подписки на некоторые классы сообщений.

E>* в некоторых случаях агент способен обрабатывать сообщения, производные от некоторого базового типа (обычный полиморфизм и работа через базовый интерфейс).


Подписываемся на этот базовый класс.


При этом отпадает необходимость подписываться на неизвестные типы сообщений и т.д.




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Конструктивная критика 2
От: remark Россия http://www.1024cores.net/
Дата: 03.04.06 21:17
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


E>>>Наличие же единственного SObjectizer Run-Time, с другой стороны, сильно упрощает использование SObjectizer. Не болит голова о том, в каком Run-Time агент зарегистрирован, в какой Run-Time нужно отсылать сообщения. И нет вопросов о том, что делать, если агент должен одновременно входить в несколько Run-Time.


R>>В MPI не понятия вхождения агента в коммутатор. Да собственно нужно ли оно? Просто при отсылке сообщения можно указать идентификатор коммутатора.


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


E>Итак, кто-то вызывает send_msg. SObjectizer блокирует свой системный словарь в режиме read-only, проверяет наличие сообщения в системе. Если сообщение есть, то создается экземпляр заявки. После этого системный словарь разблокируется, а заявка передается диспетчеру, который помещает ее в нужную очередь.


E>Все. Диспетчеризация, как видишь, происходит в месте вызова send_msg. И, поскольку системный словарь блокируется на небольшое время, да еще в read-only режиме (т.е. допускается параллельная обработка send_msg), то особых затрат на диспетчеризацию нет (есть еще блокировка на уровне диспетчера, но она зависит от типа диспетчера).


E>Так что ни через какой централизованный коммуникатор сообщения в SObjectizer не проходят. Так что я не понимаю, как соотнести коммутаторы MPI с SObjectizer-ом.



Возможно роль коммутатора MPI может играть диспетчер SObjectizer .
Я имею в виду не столько потери производительности из-за излишней централизации, сколько логическую сторону вопроса. А именно:
Допустим в приложении есть две подсистемы, которые построены на асинхронном обмене сообщениями: прикладная подсистема приёма/отправки коротких сообщений (назавём её sms) и подсистема управления работой самого приложения (назовём её app).
Я говорю о том, что было бы неплохо иметь на эти две подсистемы 2 коммутатора асинхронных сообщений (возможно ты это называешь диспетчер). При этом у этих двух коммутаторов практически не пересекались множества отправителей/получателей (хотя такое вполне допустимо).
При этом мы получаем следующие возможности:
— агент sms_checker может подписаться только на сообщения коммутатора sms, т.к. его интересуют только они
— при попытке отправить сообщение "msg_sms_receive" на коммутатор app, выдавалась бы ошибка, что такой тип сообщения не зарегистрирован в данном коммутаторе
— агент может работать (отправлять/получать сообщения) только с коммутатором своей подсистемы, пир этом его не интересует наличие/добавление/удаление/изменение других коммутаторов
— возможность настраивать некоторые параметры только для одного коммутатора, не трогая других. Например количество рабочих потоков или приоритет работы

Это как своего рода namespace'ы в с++, которые подавляют излишную корреляцию между несвязными частями и обеспечивают большую масштабируемость



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 03.04.06 21:42
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


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

R>>В твоём примере очередь должна относиться не к состоянию, а к самому объекту. А вот канал относится уже исключительно к состоянию st_connected.
R>>А что будет, если я в состоянии st_disconnected вызову какой-то метод канала — ничего хорошего. И это логическая ошибка. Т.е. прграммист скорее всего не хотел это написать — не хотел, что бы в состоянии st_disconnected происходили какие-либо вызовы канала.

E>Во-первых, обращения к каналу в состоянии st_disconnected, скорее всего, все равно потребуются. Хотя бы для инициирования переподключения

E>Во-вторых, в SObjectizer я бы выделил канал в другого агента И так на самом деле и происходит. В составе SObjectizer есть транспортные агенты (для работы с SOP и с RAW-каналами (a_cln_channel_t, a_raw_cln_channel_t)), которые в своем состояние st_disconnected дергают свой атрибут-канал для восстановления подключения. Когда подключение восстанавливается, они отсылают сообщение об этом. Если агент, занимающийся обработкой транзкций заинтересован в этом сообщении, то он подписывается на это сообщение.

E>Т.е. я не могу припомнить ситуаций, когда бы внутри объектов-агентов, какие-то атрибуты были бы восстребованы только в одном состоянии.



Вот как мне это видиться:

struct DisconnectedState : SocketState
{
    virtual void Connect(const std::string& address, int port)
    {
        goto_state(new ConnectedState(address, port));
    }
};


struct ConnectedState : SocketState
{
    ConnectedState(const std::string& address, int port)
        : socket_(address, port)
    {}

    virtual void Disconnect()
    {
        goto_state(new DisconnectedState);
    }

    virtual std::string Receive()
    {
        return socket_.Receive();
    };

    Socket socket_;
};


Прошу заметить, что DisconnectedState не нужен член Socket socket_

Ну или, например, канал приёма коротких сообщений. Допустим администратор может его включать/отключать (или это происходит автоматически). В активном состоянии каналу может требоваться достаточно много ресурсов: сокет, дополнительный поток, внутрениий буфер, какие-то кэши. А в отключённом состоянии ему это всё не нужно.




E>>>В качестве проверки такой кодогенерации был затеян проект RuCodeGen
Автор: eao197
Дата: 16.11.05
. Пока нет точного определения самого DSL (только приблизительные наметки).


R>>"А вот это попробуйте"

R>>Такая мысль у меня тоже возникла при виде всех этих макросов в коде

E>Я когда стал обдумывать DSL для описания агентов еще задумался о том, чтобы портировать SObjectizer в Ruby

E>Так что сейчас думаю, как бы этот DSL использовать одновременно и для Ruby-классов и для C++. Пока получается что-то вроде:
skip

E>В общем, есть впечатление, что в Ruby SObjectizer использовать даже удобнее было бы


Да вообще, сидишь прошраммируешь на с++ да всё пытаешься прикрутить к нему то, что в современных языках имеет удобную встроенную поддержку — то рефлекшн, то сериализацию, то фреймворки какие-то. Если уж на с++ программишь, то про другие языки лучше и не читать и не знать и уши затыкать, а то уж больно обидно становиться...
По поводу удобства такого DSL не скажу, так я ещё не прочуствовал насколько макросы были плохи


E>Кстати, что-то вроде соц.опроса. Представь, что ты присматривался бы к использованию SObjectizer. И увидел бы, что тебе нужно делать описания агентов вот в таком Ruby DSL. Отпугнуло бы это тебя?


Меня лично нет.
Хотя знаю людей, которых всяческие навороты отпугивают — им лучше, что бы всё по старому, по привычному.
Меня гораздо больше отпугивают вещи, которые такие DSL как раз призваны решать — а именно когда в коде есть много вещей, которые хорошо было бы описывать декларативно, но приходится описывать имепративно, да ещё зашивая в описание множество всяких не относящихся к делу вещей — например, описания множества однотипных классов-сущностей, описание структры БД в коде, написание запросов к БД и т.д.
Хотя такой DSL мог бы меня отпугнуть в след. ситуации: DSL в сторонней библиотеке, к которой нет хорошей документации, и я как раз решаю юзать е или нет. Тут DSL может отпугнуть, т.к. всё-таки всё услажняется: т.е. надо помимо кода ещё какие-то файлы писать, как-то дополнительно их обрабатывать и т.д.
А вот если например такой DSL уже используется в проекте, есть примеры, есть знающие люди, налажена компиляция DSL, то тут я только за.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Конструктивная критика 4
От: remark Россия http://www.1024cores.net/
Дата: 03.04.06 21:51
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Забавно. Типа "ну вы вообще конечно начинайте готовиться к завершению программы, но процесс всё равно умрёт неожиданно"


E>

E>В реальности у нас есть проектик so_sysconf (который позволяет формировать SObjectizer-приложение из кубиков-DLL как из конструктора Lego). Там есть такая задача. Решается она следующим образом -- если кому-то нужно выполнить какие-то действия перед завершением приложения, то этот агент регистрируется у sysconf-а. При начале shutdown-а всем таким агентам sysconf отсылает специальное сообщение. Агент, получив его, выполняет необходимые ему действия, а по их завершению дерегистрируется у sysconf-а. Когда sysconf видит, что все агента дерегистрировались, он выполняет реальный shutdown. Здесь есть еще одно преимущество -- агенты могут выполнять свой shutdown параллельно.


Тоже вариант.
А если надо будет 2 таких сообщения подряд обработать? В начале обработать одно, все агенты отписываются, потом отсылается сообщение, что агентам можно заново подписываться. они снова подписываются, потом рассылается второе сообщение и агенты опять отписываются
Это же эмуляция синхронности. А если бы её поддержка была в фреймворке, то было бы проще.


R>>Я об этом и говорю, что синхронный lock-подход на критический секциях по определению будет связан с дедлоками. Эту проблему не решить вообще. Все кто занимается синхронным взаимодействием об этом прекрасно осведомлены.


E>Так вот дело в том, что если SObjectizer не будет такие дедлоки диагностировать и преодолевать, то работа с их наличием будет не веселой. Они же будут эпизодическими и часто их повторение в тестовых условиях будет крайне затруднено.


E>А если заставить SObjectizer такие дедлоки диагностировать, то затраты на определение дедлока могут быть слишком высокими.


E>Так мне пока кажется.



Тут я согласен. Имел дело с крупными проектами, которые работают по синхронному принципу и основаны на lock'ах — врагу не пожелаешь



E>>>Настораживает меня фраза "все подписчики обработали сообщение". Имхо, если речь заходит о синхронном взаимодействии. то оно не может быть широковещательным, а только целенаправленным (адресным).


R>>Почему? Опять же пример с валидацией текста.


E>Мне интересно, что делать, если синхронно обрабатывающие сообщения подписчики начнут возвращать свои данные в ответ. Как все эти ответы агрегировать? Если же получаетель один, то и проблем с агрегацией нет.


Ну это уже третий вопрос. Например:

struct Result
{
private:
long result_;
public:
void setResult(long result)
{
InterlockedExchange(&result_, result_ && result);
}
};


Все агенты после обработки дёргают Result::setResult и устанавливают свой результат обработки. При необходимости результаты можно объединять по ||



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: И всё-таки она есть
От: remark Россия http://www.1024cores.net/
Дата: 03.04.06 22:08
Оценка: 13 (1)
Здравствуйте, eao197, Вы писали:

R>>Фактически сейчас есть возможность отправлять синхронные сообщения:


R>>
R>>struct SyncMessageParams
R>>{
R>>    int result;
R>>    Event messageProcessed; // Событие, что сообщение обработано
R>>    void wait(); // Ждать, пока сообщение не обработается
R>>};

R>>SyncMessageParams params;
R>>async_send("msg", &params);
R>>params.wait(); // Ждём пока сообщение будет обработано
R>>if (params.result) ...;
R>>


E>Это не правильный код

E>Сообщения должны быть динамически созданными объектами, удалением которых занимается сам SObjectizer.

R>>Тока единственная проблема — только инфрастуктура может знать, что все подписчики обработали сообщение, и установить Event messageProcessed.

R>>Поэтому нужна хотя бы минимальная поддержка со стороны инфрастуктуры — чтобы она установила Event после того как всё подписчики обработают сообщение. Необходимость такого действия можно определять например так: если параметры сообщения отнаследованы от некого SyncParams, то значит сообщение синхронное и надо установить этот Event.


Yes! И всё-таки она есть!

class SyncResult
{
private:
    Event event_;
    int result_;
        
public:
    void set(int result)
    {
        result_ = result;
        event_.Set();
    }

    int waitForProcess()
    {
        WaitForSingleObject(event_);
        return result_;
    }
};

class SyncMessage
{
private:
    SyncResult& sync_;
    int result_;

public:
    SyncMessage(SyncResult& sync)
        : sync_(sync)
        , result(0)
    {}

    void setResult(int result)
    {
        // По некому закону объединяем result_ и result
    }

    //...

    ~SyncMessage()
    {
                // Это выполняется при удалении сообщения - очевидно, что это происходит после обработки сообщения всеми подписчиками
        sync_.set(result_);
    }};


int main()
{
    SyncResult syncResult;
    so4::send("msg", new SyncMessage(syncResult));
    int syncProcessResult = syncResult.waitForProcess();
}




Вся работа с потоками на месте.
Получателей может быть один или много (надо только запрограммировать закон объединения результата).
При желании (для уменьшения дедлоков) можно помимо блокируещего метода waitForProcess() добавить метод bool checkIsMessageProcessed(). Или не устанавливать Event при окончании обработки, а вызывать установленный калбэк.




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: Конструктивная критика 4
От: remark Россия http://www.1024cores.net/
Дата: 03.04.06 22:10
Оценка:
Здравствуйте, remark, Вы писали:

R>
R>struct Result
R>{
R>private:
R>long result_;
R>public:
R>void setResult(long result)
R>{
R>InterlockedExchange(&result_, result_ && result);
R>}
R>};
R>



Это, конечно, неправильно — надо InterlockedCompareExchange

R>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: Конструктивная критика 1
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.04.06 08:07
Оценка:
Здравствуйте, remark, Вы писали:

R>Тогда у меня 2 вопроса:

R>1. Зачем описывать сам класс сообщения отдельно. Можно обойтись только SOL4_MSG_START, который заодно будет создавать и описание класса. Это, конечно, немного "урезает" возможности сообщений, т.е. в них будет нельзя добавить своего кода. Но в некоторых местах дополнительные ограничения идут только на пользу.
R>Иначе, во-первых, дублирование со всеми вытекающими.
R>Во-вторых, не очень прозрачные возможности, типа добавить какой-то член в класс сообщения, но не описать его в SOL4_MSG_START.

Здесь несколько факторов.
Во-первых, за макросами SOL4_MSG_START/SOL4_MSG_FIELD/SOL4_MSG_FINISH скрывается достаточно много кодогенерации, которую не хочется выносить на уровень заголовочных файлов. А если заставлять пользователя описывать сообщения исключительно через макросы SOL4_MSG_*, то такое описание придется делать в заголовочных файлах -- иначе это сообщение не будет доступно в других единицах трансляции.

Во-вторых, нельзя лишать пользователя возможности добавлять собственный код в сообщения. По следующим причинам:
* в сообщении кроме конструктора по-умолчанию в подавляющем большинстве случаев приходится делать дополнительные конструкторы, чтобы создавать проинициализированный объект сообщения одной строкой:
new msg_some_action( param1, param2, param3 );

вместо:
m = new msg_some_action();
m->param1 = param1;
m->param2 = param2;
m->param3 = param3;

* в сообщении с данным следует еще определять метод checker, который сможет проверять корректность сообщения;
* в SOL4_MSG_FIELD нужно перечислять только поля простейших типов, либо типов, сериализуемых через ObjESSty. Но это очень мало для полноценной работы. Кроме того, через SOL4_MSG_FIELD нужно перечислять только поля, доступные через SOP. Очень часто сообщение вообще не должно быть доступно через SOP, но зато должно содержать поля сложных типов (указатели, в том числе и умные, STL-контейнеры, сложные пользовательские типы);
* я не хотел, чтобы SObjectizer накладывал жесткие условия на типы сообщений. Вроде наследования от общего корня. Или каких-то органичений на состав полей/методов. Ведь если этих ограничений нет, то в качестве сообщений можно использовать объекты любых типов. Даже типов, которые появились в приложении до SObjectizer-а. Например, зачем запрещать человеку отсылать в качестве сообщения std::vector, если ему это действительно нужно?

R>2. Отпадают все плюсы использования текстовых идентификаторов для сообщений, о которых ты писал! Если рантайм может преобразовывать сообщения в/из текстового представления, то в программе можно использовать исключительно типы в качестве идентификаторов сообщений. Но при этом не теряется возможность обмена с внешними подсистемами и "ручного" ввода сообщений внутрь системы.


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

R>Да, только я имею в виду, что при варианте с наследованием классов сообщений и не надо будет таких извращений:


E>>* агент-коммуникатор способен работать с любыми сообщениями для маршаллинга/демаршаллинга, используя для этого информацию из системного словаря SObjectizer;


R>Подписываемся на базовый класс сообщений.

R>При этом как сам базовый класс, так и ран-тайм предоставляет некоторые базовые функции для работы с этим сообщением.

Я не хотел принципиально, чтобы для сообщений был общий корень иерархии, из которого все растет.

E>>* некий агент способен обрабатывать разнотипные сообщения, если ему не важно содержимое этих сообщений, а важен сам факт их наличия;


R>Это я не очень понял что значит.


Ну например, есть агент, который в случае какой-нибудь аварии отсылает SMS-ку куда-нибудь. Этот агент в конфиге получает информацию, что ему нужно подписаться на сообещения a_fire_monitor.msg_alarm, a_electric_power_monitor.msg_alarm, a_floor_security.msg_alarm. Каждое из этих сообщений имеет собственный тип, но для агента a_alarm_sms_sender это не важно -- он не будет анализировать их содержимое.

Еще один пример. Некий агент может собирать статистику о количестве указанных сообщений в системе за последнее время. Например, если количество сообщений msg_trx_failed за последние 15 минут превысило 20%, то нужно об этом как-то сигнализировать. Такому агенту для сбора статистики вообще безразлично, какие именно сообщения он будет мониторить.

R>Но возможно тоже можно решить с помощью подписки на некоторые классы сообщений.


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

E>>* в некоторых случаях агент способен обрабатывать сообщения, производные от некоторого базового типа (обычный полиморфизм и работа через базовый интерфейс).


R>Подписываемся на этот базовый класс.


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Конструктивная критика 2
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.04.06 08:23
Оценка:
Здравствуйте, remark, Вы писали:

R>Допустим в приложении есть две подсистемы, которые построены на асинхронном обмене сообщениями: прикладная подсистема приёма/отправки коротких сообщений (назавём её sms) и подсистема управления работой самого приложения (назовём её app).

R>Я говорю о том, что было бы неплохо иметь на эти две подсистемы 2 коммутатора асинхронных сообщений (возможно ты это называешь диспетчер). При этом у этих двух коммутаторов практически не пересекались множества отправителей/получателей (хотя такое вполне допустимо).
R>При этом мы получаем следующие возможности:
R>- агент sms_checker может подписаться только на сообщения коммутатора sms, т.к. его интересуют только они
R>- при попытке отправить сообщение "msg_sms_receive" на коммутатор app, выдавалась бы ошибка, что такой тип сообщения не зарегистрирован в данном коммутаторе
R>- агент может работать (отправлять/получать сообщения) только с коммутатором своей подсистемы, пир этом его не интересует наличие/добавление/удаление/изменение других коммутаторов
R>- возможность настраивать некоторые параметры только для одного коммутатора, не трогая других. Например количество рабочих потоков или приоритет работы

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

R>Это как своего рода namespace'ы в с++, которые подавляют излишную корреляцию между несвязными частями и обеспечивают большую масштабируемость


Аналогом namespace-ов C++ в SObjectizer является включение имени namespace из C++ в имена агентов и коопераций SObjectizer. Например, у меня есть агенты:
aag_3::smpp_smsc::some_operator::a_channel
aag_3::smpp_smsc::some_operator::a_send_history
aag_3::smpp_smsc::some_operator::a_receive_history

aag_3::smpp_smsc::another_operator::a_channel
aag_3::smpp_smsc::another_operator::a_send_history
aag_3::smpp_smsc::another_operator::a_receive_history

aag_3::smsc_map::default::a_router
aag_3::smsc_map::default::a_state_mon
aag_3::smsc_map::another_server::a_router
aag_3::smsc_map::another_server::a_state_mon

mbsms_gate_1::some_provider::a_send_retranslator
mbsms_gate_1::some_provider::a_receive_retranslator

mbsms_gate_1::another_provider::a_receive_retranslator
mbsms_gate_1::another_provider::a_receive_retranslator


И все. Никаких проблем


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.04.06 08:36
Оценка:
Здравствуйте, remark, Вы писали:

E>>Т.е. я не могу припомнить ситуаций, когда бы внутри объектов-агентов, какие-то атрибуты были бы восстребованы только в одном состоянии.


R>Вот как мне это видиться:


R>
R>        goto_state(new ConnectedState(address, port));
R>        goto_state(new DisconnectedState);
R>


R>Прошу заметить, что DisconnectedState не нужен член Socket socket_


А теперь представь, что все агенты в SObjectizer вынуждены менять свои состояния через создание нового объекта-состояния. Агентов могут быть сотни тысяч. А некоторые агенты могут менять свое состояние сотни раз в секунду. И это при том, что реальной очистки ресурсов будут требовать считанные единицы действительно тяжеловесных агентов.

R>Ну или, например, канал приёма коротких сообщений. Допустим администратор может его включать/отключать (или это происходит автоматически). В активном состоянии каналу может требоваться достаточно много ресурсов: сокет, дополнительный поток, внутрениий буфер, какие-то кэши. А в отключённом состоянии ему это всё не нужно.


Ну и в чем проблема? Сокет по любому придется закрывать. Вызовешь у объекта типа CSocket метод close() при смене состояния и все.
Поток уснет на каком-нибудь condition variable и никаких ресурсов требовать не будет. Кэши почистятся.
Имхо, повторное создание/уничтожение всего этого хозяйства при смене состояния будет гораздо дороже, чем однократное создание его с последующим переводом в standby/ready.

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


E>>Кстати, что-то вроде соц.опроса. Представь, что ты присматривался бы к использованию SObjectizer. И увидел бы, что тебе нужно делать описания агентов вот в таком Ruby DSL. Отпугнуло бы это тебя?


R>Меня лично нет.

R>Хотя знаю людей, которых всяческие навороты отпугивают — им лучше, что бы всё по старому, по привычному.
R>Меня гораздо больше отпугивают вещи, которые такие DSL как раз призваны решать — а именно когда в коде есть много вещей, которые хорошо было бы описывать декларативно, но приходится описывать имепративно, да ещё зашивая в описание множество всяких не относящихся к делу вещей — например, описания множества однотипных классов-сущностей, описание структры БД в коде, написание запросов к БД и т.д.
R>Хотя такой DSL мог бы меня отпугнуть в след. ситуации: DSL в сторонней библиотеке, к которой нет хорошей документации, и я как раз решаю юзать е или нет. Тут DSL может отпугнуть, т.к. всё-таки всё услажняется: т.е. надо помимо кода ещё какие-то файлы писать, как-то дополнительно их обрабатывать и т.д.
R>А вот если например такой DSL уже используется в проекте, есть примеры, есть знающие люди, налажена компиляция DSL, то тут я только за.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Конструктивная критика 4
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.04.06 08:39
Оценка:
Здравствуйте, remark, Вы писали:

R>А если надо будет 2 таких сообщения подряд обработать? В начале обработать одно, все агенты отписываются, потом отсылается сообщение, что агентам можно заново подписываться. они снова подписываются, потом рассылается второе сообщение и агенты опять отписываются


Что-то я про два сообщения подряд не понял.

E>>Мне интересно, что делать, если синхронно обрабатывающие сообщения подписчики начнут возвращать свои данные в ответ. Как все эти ответы агрегировать? Если же получаетель один, то и проблем с агрегацией нет.


R>Ну это уже третий вопрос. Например:


R>
R>struct Result
R>{
R>private:
R>long result_;
R>public:
R>void setResult(long result)
R>{
R>InterlockedExchange(&result_, result_ && result);
R>}
R>};
R>


R>Все агенты после обработки дёргают Result::setResult и устанавливают свой результат обработки. При необходимости результаты можно объединять по ||


Это тривиальный случай с возвратом long-а. Он не интересен. На практике как раз синхронность требовалась когда в сообшении-запросе передавался большой объем данных, а назад требовалось получить так же сложный объект с результатами их обработки/анализа/проверки.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: И всё-таки она есть
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.04.06 08:45
Оценка:
Здравствуйте, remark, Вы писали:

R>Yes! И всё-таки она есть!


R>
R>class SyncResult
R>{
R>private:
R>    Event event_;
R>    int result_;
        
R>public:
R>    void set(int result)
R>    {
R>        result_ = result;
R>        event_.Set();
R>    }

R>    int waitForProcess()
R>    {
R>        WaitForSingleObject(event_);
R>        return result_;
R>    }
R>};

R>class SyncMessage
R>{
R>private:
R>    SyncResult& sync_;
R>    int result_;

R>public:
R>    SyncMessage(SyncResult& sync)
R>        : sync_(sync)
R>        , result(0)
R>    {}

R>    void setResult(int result)
R>    {
R>        // По некому закону объединяем result_ и result
R>    }

R>    //...

R>    ~SyncMessage()
R>    {
R>                // Это выполняется при удалении сообщения - очевидно, что это происходит после обработки сообщения всеми подписчиками
R>        sync_.set(result_);
R>    }};


R>int main()
R>{
R>    SyncResult syncResult;
R>    so4::send("msg", new SyncMessage(syncResult));
R>    int syncProcessResult = syncResult.waitForProcess();
R>}
R>


R>




Это вариант для синхронного взаимодействия только в рамках одного процесса.

R>При желании (для уменьшения дедлоков) можно помимо блокируещего метода waitForProcess() добавить метод bool checkIsMessageProcessed().


Имхо, вместо метода checkIsMessageProcessed() лучше ввести в waitForProcess() тайм-аут ожидания результата. И выставлять тайм-аут в 0, если требуется получить результат немедленно.

R> Или не устанавливать Event при окончании обработки, а вызывать установленный калбэк.


Зачем callback, если в SObjectizer есть механизм событий/сообщений?
Это те же самые callback-и.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: Dy64 Германия www.dy64.de
Дата: 04.04.06 09:16
Оценка: +1
Здравствуйте, Евгений Охотников, Вы писали:

ЕО>Статья:

ЕО>SObjectizer: I Love This Game!
Автор(ы): Евгений Охотников
Дата: 31.03.2006
Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.


ЕО>Авторы:

ЕО> Евгений Охотников

ЕО>Аннотация:

ЕО>Данная статья знакомит читателя с проектом SObjectizer -- инструментом для агентно-ориентированного программирования на C++. Раcсказывается о его истории, текущем состоянии и ближайших перспективах. Обсуждаются некоторые преимущества, которые дает SObjectizer, а также некоторые его недостатки и проблемы.

Статью прочитал.
Проделан не малый труд, любой уважающий себя человек ценит то что он сделал,
Но (мое ИМХО) SObjectizer — это архаизм, который уже давно с лихвой "покрывается" современным
подходом к разработке и написанными Framework'ами.
Ваше время бесспорно было в конце 90х, но на сегодняшний момент все крупные фирмы в той или иной
степени переходят с С++ на более продвинутые языки. Не возможно, да и не нужно, все написать на С# или Java, всегда будет оставаться необходимость в C++ или Assembler'ных вставках, но, заметьте,
их использование сводиться к минимуму.
Дмитрий.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.04.06 09:40
Оценка:
Здравствуйте, Dy64, Вы писали:

D>Но (мое ИМХО) SObjectizer — это архаизм, который уже давно с лихвой "покрывается" современным

D>подходом к разработке и написанными Framework'ами.
D>Ваше время бесспорно было в конце 90х, но на сегодняшний момент все крупные фирмы в той или иной
D>степени переходят с С++ на более продвинутые языки. Не возможно, да и не нужно, все написать на С# или Java, всегда будет оставаться необходимость в C++ или Assembler'ных вставках, но, заметьте,
D>их использование сводиться к минимуму.

И?

Какого-то определенного вывода в ваших словах я, к сожалению, не увидел.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Конструктивная критика 4
От: Аноним  
Дата: 04.04.06 23:32
Оценка: 1 (1)
Здравствуйте, remark, Вы писали:

R>4. Синхронные сообщения — всё-таки они нужны. Их отсутствие сужает область применения, если не в два раза, то по крайней мере на треть.

R>Это всё равно как заставить у всех функций использовать возвращаемый тип только void.

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

На мой взгляд и синхронный, и асинхронный способы обладают своими недостатками и преимуществами. При любом варианте взаиммодействия имеем: в синхронном варианте — дедлоки (deadlock), в асинхронном — ливлоки (livelock). Синхронные приложения проще отлаживать (есть возможность воспроизвести поведение программы, а значит повторить ошибку). Асихронные приложения очень тяжело отлаживать, но зато в них имеется больший потенциал производительности.

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

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

Re[3]: Идеи создаются на бумаге
От: vip_delete  
Дата: 05.04.06 21:50
Оценка: -1 :)
Доброго времени суток.
У меня сложилось впечатление, что автор дествительно профессионал в с++. Все ниже контретно ни к кому не относиться, а является общим моим мнением в отношении программистов, которые пишут кривой работающий код.

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

Я больше чем убежден, что прежде чем писать ТАКИЕ проекты надо знать как минимум логику работы
1) Процессора (выборка-исполенние)
2) Памяти
3) Контроллеров прерываний и их взаимодействие с процем
...ну и, короче, знать основы работы на НИЗАХ как и почему и хотеть(!) интересоваться этим дальше.
А именно для того, чтобы не изобретать велосипеды. Зная железо вы будете постоянно проводить аналогии с программированием наверху! Я никогда не возьму на работу программера на .NET если он не знает ассемблера, так как его грамотность в архитектуре приложений скорее всего оставляет желать лучшего. (А это самое главное, синтаксис языка — на самом последнем месте).
Заметьте все части компа работают в ассинхронном режиме, и ничего не валится. Причем некоторые моменты поистине гениальны в железе. Взять для примера хоть алгоритм работы 2-х кешей в двух ядерном процессоре — подика придумай как его на SObjectizer написать (теоретически). Я уверен все накроется или, по крайней мене, доставка сообщений будет не оптимальна. Есть замечательные слова — разделя и властвуй. У вас есть иерархический протокол сообщений с возможностью надстройки или смены протокола? Тут зашел разговор про маршрутизацию, Сразу же надо знать почему в компе ее нет, а в локальных/глобальных сетях есть. В чем плюсы и недостатки. От куда столько сетевых протоколов и как они работают. Тогда и не было бы демогогии что лучше. Это все к вопросу о велосипедах.

Не надо тут говорить, что у SObjectizer уникальная идея. я больше чем убежден (более-менее серьезный разговор это развеет) что это не так.

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

Собственно интересна ранняя история такой идеи, с чего бы вдруг ей зародиться? И если она зародилась в 90, то в прежднем виде сейчас быть не должна хотя бы ради конкурентноспособности.

Спасибо
Re[4]: Идеи создаются на бумаге
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.04.06 07:58
Оценка: +1
Здравствуйте, vip_delete, Вы писали:

_>Я больше чем убежден, что прежде чем писать ТАКИЕ проекты


Под "ТАКИМИ" понимается SObjectizer? Или вообще разработка библиотек и фреймворков?

_> надо знать как минимум логику работы

_>1) Процессора (выборка-исполенние)
_>2) Памяти
_>3) Контроллеров прерываний и их взаимодействие с процем
_>...ну и, короче, знать основы работы на НИЗАХ как и почему и хотеть(!) интересоваться этим дальше.

Это очень спорное утверждение, выходящее за рамки обсуждения SObjectizer, но все-таки можно ли его обосновать?

_>А именно для того, чтобы не изобретать велосипеды. Зная железо вы будете постоянно проводить аналогии с программированием наверху! Я никогда не возьму на работу программера на .NET если он не знает ассемблера, так как его грамотность в архитектуре приложений скорее всего оставляет желать лучшего. (А это самое главное, синтаксис языка — на самом последнем месте).


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

_>Заметьте все части компа работают в ассинхронном режиме, и ничего не валится. Причем некоторые моменты поистине гениальны в железе. Взять для примера хоть алгоритм работы 2-х кешей в двух ядерном процессоре — подика придумай как его на SObjectizer написать (теоретически). Я уверен все накроется или, по крайней мене, доставка сообщений будет не оптимальна. Есть замечательные слова — разделя и властвуй. У вас есть иерархический протокол сообщений с возможностью надстройки или смены протокола? Тут зашел разговор про маршрутизацию, Сразу же надо знать почему в компе ее нет, а в локальных/глобальных сетях есть. В чем плюсы и недостатки. От куда столько сетевых протоколов и как они работают. Тогда и не было бы демогогии что лучше. Это все к вопросу о велосипедах.


Вот здесь я вообще потерял нить рассуждений.
Зачем писать на SObjectizer алгоритм работы 2-х кэшей? Для имитационного моделирования? Если так, то про какую оптимальность доставки сообщений может идти речь?
Зачем какой-то иерархический протокол доставки сообщений (с упоминанием локальных и глобальных сетей)?
Мне кажется, что этот абзац содержит в себе какие-то внутренние противоречия. И не понятно, какое отношение он имеет к велосипедам вообще и к SObjectizer в частности.

Если же вы думаете, что при разработке программного обеспечения (software) нужно искать аналогии в аппаратуре (hardware), то может быть скажете, где в аппаратуре можно найти аналогию сборки мусора (GC)?
Это я к тому, что на мой взгляд, в мире не так уж много принципиально разных идей. И какая-нибудь идея может иметь разные воплощения в разных областях, будь то software или hardware (как то асинхронное взаимодействие). Вот только совсем не факт, что какая-то реализация идеи в hardware должна становиться догмой в software.

_>Не надо тут говорить, что у SObjectizer уникальная идея. я больше чем убежден (более-менее серьезный разговор это развеет) что это не так.


А где было сказано, что SObjectizer -- это уникальная идея?
Наоборот, подчеркивалось, что многие вещи были взяты из других источников (см., например, сообщение AVC
Автор: AVC
Дата: 10.01.06
).
А люди, знакомые с Erlang-ом сразу говорят, что SObjectizer выглядит, как попытка реализовать Erlang в C++.
Повторюсь, в мире не так уж много оригинальных идей.

Если в чем-то и есть уникальность SObjectizer-а, так это в самом факте его существования. SObjectizer -- это не фантазия, не академическая разработка, не доклад на научной конференции. Это реально существующий и использующийся инструмент. Его можно скачать, скомпилировать, запустить. Если понравиться, то взять и применить. И обсуждать, и критиковать его можно только лишь по одной, самой важной причине -- он есть.

А это позволяет заинтересовавшись SObjectizer-ом посмотреть на него пристальнее, покрутить, повертеть, примерить. Найти недостатки, указать на них. Его можно развивать. Собственно, вся цель выпуска SObjectizer в мир состоит в том, чтобы развивать его не только так, как мы это видим. Но и так, как могут увидеть и другие люди.

_>Несмотря на такую критику я не против такой идеи, только меня насторожило следующее: автор сказал, что у них нет идей, что делать дальше.


Не говорил я такого.
Я сказал:

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

Идеи как раз есть. Только это все наши собственные идеи. А хотелось бы услышать новые, неожиданные, из тех областей, про которые мы, возможно, даже не слышали. Чтобы в идеале кто-то взял и сказал: "Я считаю, что SObjectizer мог бы пригодиться вот здесь, но для этого нужно, чтобы он поддерживал то-то и то-то."
А мы бы в ответ: "Ух ты! А ведь действительно... Погнали!"
Но еще важнее, чтобы реализованная в SObjectizer идея была бы опробованна на практике. Чтобы не оказалось, что мы сделали фишку, предоставляющую только академический интерес.

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

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

_>У людей в белых халатах из Research-центров всегда есть куча идей и куча денег — нет времени это все реализовать.


Мы не люди в белых халатах из Research центров.
Интервэйл (пока) не Microsoft, не Sun, не HP, не Siemens и, тем более, не IBM. Так что у нас элементарно нет кучи денег на то, чтобы нанять 5-10 человек на полный рабочий день для клепания новых версий SObjectizer-а.
И при этом, не смотря на отсутствие белых халатов и кучи денег, времени все равно не хватает.

Если же у кого есть куча денег, которые он хочет вложить в Research, то мы с удовольствием поможем эту кучу освоить

_>Собственно интересна ранняя история такой идеи, с чего бы вдруг ей зародиться?


Ранняя история описывалась в ранней же моей статье История одного проекта. Но если этого не достаточно, то я могу сделать небольшой экскурс от истоков до сегодняшнего дня.

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


А нынешний вид SObjectizer и так оОочень сильно отличается от того, что было в самом начале.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: Идеи создаются на бумаге
От: Аноним  
Дата: 06.04.06 10:05
Оценка: :)
Здравствуйте, eao197, Вы писали:

E>Под "ТАКИМИ" понимается SObjectizer? Или вообще разработка библиотек и фреймворков?

Имеется ввиду проекты с предполагаемым числом строк в 100000.

_>> надо знать как минимум логику работы

_>>1) Процессора (выборка-исполенние)
_>>2) Памяти
_>>3) Контроллеров прерываний и их взаимодействие с процем
_>>...ну и, короче, знать основы работы на НИЗАХ как и почему и хотеть(!) интересоваться этим дальше.

E>Это очень спорное утверждение, выходящее за рамки обсуждения SObjectizer, но все-таки можно ли его обосновать?

Просто: Мне кажется, что многие менеджеры обработки данных: агент, роутер, свич, светофор наконец. имеет одну и ту же природу — обработывают данные. Знание плюсов и минусов одинаковых по природе объектов, но различающийхся по способу обработки развивает кругозор, позволяет быстрее входить "в тему", понимать логику работы, предлагать лучшие варианты сходу (так как у работника большой кругозор!). Мне трудно судить по вашему знанию аппаратных средств, но компьютер устроен так же — посылка сообщений некоторым своим частям через прерывания, которых есть приоритет, на прерывания можно "подписаться" можно посылать прерывания по таймеру, замаскировать их ну и тд. Наверно, идея понятна, кто владеет информацией — владеет всем миром.

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

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

E>Вот здесь я вообще потерял нить рассуждений.

E>Зачем писать на SObjectizer алгоритм работы 2-х кэшей? Для имитационного моделирования? Если так, то про какую оптимальность доставки сообщений может идти речь?
E>Зачем какой-то иерархический протокол доставки сообщений (с упоминанием локальных и глобальных сетей)?
E>Мне кажется, что этот абзац содержит в себе какие-то внутренние противоречия. И не понятно, какое отношение он имеет к велосипедам вообще и к SObjectizer в частности.
Тут надо понимать некоторую аналогию — кеши — это два зеркала в интеренета, например (опять аналогия из жизни). и требуется обеспечить синхронизацию между ними.

E>Если же вы думаете, что при разработке программного обеспечения (software) нужно искать аналогии в аппаратуре (hardware), то может быть скажете, где в аппаратуре можно найти аналогию сборки мусора (GC)?

E>Это я к тому, что на мой взгляд, в мире не так уж много принципиально разных идей. И какая-нибудь идея может иметь разные воплощения в разных областях, будь то software или hardware (как то асинхронное взаимодействие). Вот только совсем не факт, что какая-то реализация идеи в hardware должна становиться догмой в software.
Верно не факт, что идея из hardware, что должна становиться догмой в software, но надо ее знать, чтобы знать, чем идея в software лучше. А то вот я написал HelloWord на SObjectizer, если бы я не знаю другие языки, я бы сказал — круто (серое вещество не работает). А так я начинаю сравнивать со всеми другими языками на автомате и оценивать его возможности.
Про GC не думал, но это не значит что ее нет, но и не значит что она есть.

_>>Не надо тут говорить, что у SObjectizer уникальная идея. я больше чем убежден (более-менее серьезный разговор это развеет) что это не так.


E>Не говорил я такого.

E>Я сказал:
E>

E>Его возможностей (как внутреннего инструмента) вполне достаточно. Поэтому можно сказать, что нет свежих идей, которые бы дали новый толчок развитию SObjectizer.

E>Идеи как раз есть. Только это все наши собственные идеи. А хотелось бы услышать новые, неожиданные, из тех областей, про которые мы, возможно, даже не слышали. Чтобы в идеале кто-то взял и сказал: "Я считаю, что SObjectizer мог бы пригодиться вот здесь, но для этого нужно, чтобы он поддерживал то-то и то-то."
E>А мы бы в ответ: "Ух ты! А ведь действительно... Погнали!"
E>Но еще важнее, чтобы реализованная в SObjectizer идея была бы опробованна на практике. Чтобы не оказалось, что мы сделали фишку, предоставляющую только академический интерес.

E>Ну, например, время от времени возникает желание сделать сообщение-сигнал. Т.е., если сообщение A было отосланно, но еще не обработано, то повторые отсылки A не приводят к появлению новых экземпляров A. Или иногда высказываются предположение, что очереди заявок к агентам можно было бы ограничить по глубине. Скажем, стоит в очереди 2000 событий, новое не ставится, т.к. агент перегружен. Или идея перехвата сообщений с возможностью возобновления его обработки в дальнейшем. Или идея о сохранении сообщений в очередях на диске для обеспечения их гарантированной доставки...

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

E>Хочется сохранить разумный баланс между функциональностью SObjectizer и сложностью его реализации. Чтобы не превратить SObjectizer в барахолку неиспользуемых возможностей, которую очень трудно сопровождать.

А это уже вопрос архитектуры, разделения проекта на функциональные части, огранизации производства. 2-3 человека это сопросождать не смогут 100%.

_>>У людей в белых халатах из Research-центров всегда есть куча идей и куча денег — нет времени это все реализовать.


E>Ранняя история описывалась в ранней же моей статье История одного проекта. Но если этого не достаточно, то я могу сделать небольшой экскурс от истоков до сегодняшнего дня.

E>А нынешний вид SObjectizer и так оОочень сильно отличается от того, что было в самом начале.
Отлично, осталось только добавить, то что нужно вам. А что добавлять должны решать как минимум 3 человека
Надо написать список плюсов и минусов (а для этого как я говорил надо иметь знания в других областях) прийти к общему мнению.

В общем я как всегда сумбурно все написал, что никто ничего не понял. сорри если что.
Re[6]: Идеи создаются на бумаге
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.04.06 15:52
Оценка:
Здравствуйте, Аноним, Вы писали:

E>>Зачем писать на SObjectizer алгоритм работы 2-х кэшей? Для имитационного моделирования? Если так, то про какую оптимальность доставки сообщений может идти речь?

А>Тут надо понимать некоторую аналогию — кеши — это два зеркала в интеренета, например (опять аналогия из жизни). и требуется обеспечить синхронизацию между ними.

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

А>Верно не факт, что идея из hardware, что должна становиться догмой в software, но надо ее знать, чтобы знать, чем идея в software лучше. А то вот я написал HelloWord на SObjectizer, если бы я не знаю другие языки, я бы сказал — круто (серое вещество не работает). А так я начинаю сравнивать со всеми другими языками на автомате и оценивать его возможности.


Мысль, вероятно правильная, но вот аналогия, имхо, не очень
Оценивать язык программирования на основании внешнего вида примера HelloWorld -- это весьма наивно.
К тому же SObjectizer -- это не язык программирования. Это инструмент, который в данное время предназначен для одного (и только одного) языка. Так что, если уж его сравнивать, что с чем нибудь подобным. А то ведь можно пытаться сравнить детектив и пиво, т.к. они являются средством времяпрепровождения.

И давайте взглянем на этот вопрос с другой стороны. Есть читатели, которые, как говорится, "в теме". Они могут сравнить SObjectizer, к примеру с Erlang или с SWITCH. Но ведь это очень специфическая область, про которые не так уж много читателей знают. Для кого-то может стать вообще откровением, что подобный инструмент существует (как для меня существование Erlang в свое время). Этот кто-то может примерить SObjectizer к своей задаче. А кто-то может заинтересоваться данной темой и пойти искать аналогичные инструменты.

Да и если пробовать составить впечатление о программировании на SObjectizer, то лучше делать это не на HelloWorld, а на более сложных примерах. Скажем, на high_traffic/server.cpp и high_traffic/client.cpp.

А>Могу предложить так же реализовать обработку ответа от агента: перегружен, поставил в очередь, такое сообщение уже существует. А так же некоторые сервисы агента — уведодомление о доставке, проверка статуса сообщения.


Ну вот, видите, сколько сразу предложений возникло. Для этого SObjectizer и выносится на обозрение.
Вот вам, к примеру, такая функциональность кажется полезной. А вот мне -- нет, т.к. я считаю, что подобные вещи делают связь между агентами более жесткой. Что приведет к проблемам масштабирования приложения, когда часть агентов потребуется переместить в другой процесс на другой узел сети. Вот у меня такое зашоренное мнение. И было бы интересно услышать контраргументы.

E>>Хочется сохранить разумный баланс между функциональностью SObjectizer и сложностью его реализации. Чтобы не превратить SObjectizer в барахолку неиспользуемых возможностей, которую очень трудно сопровождать.

А>А это уже вопрос архитектуры, разделения проекта на функциональные части, огранизации производства. 2-3 человека это сопросождать не смогут 100%.

Угу. А еще вопрос целесообразности производства

_>>>У людей в белых халатах из Research-центров всегда есть куча идей и куча денег — нет времени это все реализовать.


А>Отлично, осталось только добавить, то что нужно вам. А что добавлять должны решать как минимум 3 человека


Вот как раз третьего и не хватает
Так что, можно сказать, озираемся по сторонам и спрашиваем у окружающих: "Третьим будешь?"


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Конструктивная критика 4
От: remark Россия http://www.1024cores.net/
Дата: 06.04.06 18:20
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, remark, Вы писали:


R>>4. Синхронные сообщения — всё-таки они нужны. Их отсутствие сужает область применения, если не в два раза, то по крайней мере на треть.

R>>Это всё равно как заставить у всех функций использовать возвращаемый тип только void.

А>Позволю себе не согласиться с автором данного тезиса. Наоборот, жестко синхронная система подобна последовательному алгоритму, только в распределенном варианте исполнения. Более того синхронность и асинхронность — это всего лишь примитивы реализации взаимодействия, обладающие разными семантиками. И только от поставленной задачи зависит какой сопсоб взаимодействия агентов (компонент, процессов, потоков и прочее.....) лучше всего выбрать.


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




А>На мой взгляд и синхронный, и асинхронный способы обладают своими недостатками и преимуществами.


Бесспорно. Но при этом нет способа, который "лучше по всем параметрам", поэтому-то они и существуют оба.


А>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: И всё-таки она есть
От: remark Россия http://www.1024cores.net/
Дата: 06.04.06 18:22
Оценка:
Здравствуйте, eao197, Вы писали:

E>Это вариант для синхронного взаимодействия только в рамках одного процесса.



Ну это я так, больше в качестве задачки


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[7]: Конструктивная критика 4
От: remark Россия http://www.1024cores.net/
Дата: 06.04.06 18:37
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>А если надо будет 2 таких сообщения подряд обработать? В начале обработать одно, все агенты отписываются, потом отсылается сообщение, что агентам можно заново подписываться. они снова подписываются, потом рассылается второе сообщение и агенты опять отписываются


E>Что-то я про два сообщения подряд не понял.


Ну в том примере про so_sysconf ты написал, что при необходимости выполнить некий тип действия (shutdown приложения), который фактически является синхронным (посылается сообщение и только после обработки сообщения всеми заинтересованными лицами выполнение продолжается), использовалась очень сложная схема: агенты регистрировались у некого вспомогательного объекта, потом обрабатывали сообщение, потом разрегистрировались у вспомогательного объекта, и после разрегистрации всех агентов, считалось, что обработка сообщения закончилась.
Я говорю о масштабируемости такого решения. А если надо будет выполнить несколько таких действий подряд? То агентам придётся постоянно то регистрироваться, то разрегистрироваться у вспомогательного объекта? А если надо будет выполнять несколько типов таких действий, то придётся создать несколько вспомогательных объектов?




E>Это тривиальный случай с возвратом long-а. Он не интересен. На практике как раз синхронность требовалась когда в сообшении-запросе передавался большой объем данных, а назад требовалось получить так же сложный объект с результатами их обработки/анализа/проверки.


Ну это уже зависит от задачи! Что надо сделать, то и надо реализовать. Если результаты надо объединять по &&, то надо объединять по &&. Если надо объединять по ||, то надо объединять по ||. Если надо складывать, то надо складывать. Если надо все результаты складывать в один контейнер, то надо складывать.
Возможности синхронной обработки тут ни при чём.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: Конструктивная критика 4
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.04.06 08:01
Оценка:
Здравствуйте, remark, Вы писали:

E>>Что-то я про два сообщения подряд не понял.


R>Ну в том примере про so_sysconf ты написал, что при необходимости выполнить некий тип действия (shutdown приложения), который фактически является синхронным (посылается сообщение и только после обработки сообщения всеми заинтересованными лицами выполнение продолжается), использовалась очень сложная схема: агенты регистрировались у некого вспомогательного объекта, потом обрабатывали сообщение, потом разрегистрировались у вспомогательного объекта, и после разрегистрации всех агентов, считалось, что обработка сообщения закончилась.


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

R>Я говорю о масштабируемости такого решения. А если надо будет выполнить несколько таких действий подряд? То агентам придётся постоянно то регистрироваться, то разрегистрироваться у вспомогательного объекта? А если надо будет выполнять несколько типов таких действий, то придётся создать несколько вспомогательных объектов?


Здесь видно две стороны масштабируемости. Во-первых, сколько агентов смогут обрабатывать одну операцию (тот же shutdown?). Если операция выполняется асинхронно, то ограничений не видно -- агенты смогут выполнять ее параллельно. Причем, что важно, большая часть агентов начнет обрабатывать shutdown одновременно, поскольку многие будут работать на параллельных нитях. А вот если shutdown делать синхронным, то нужно будет дергать агентов поочереди, ожидать завершение, дергать следующего и т.д. Мало того, что при большом количестве агентов эта операция будет не быстрой, так еще и система будет наполовину заглушена, наполовину работать в обычном режиме. Если же агенты довольно плотно взаимодействуют друг с другом, то что будет твориться в такой полузаглушенной системе...

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

R>Ну это уже зависит от задачи! Что надо сделать, то и надо реализовать. Если результаты надо объединять по &&, то надо объединять по &&. Если надо объединять по ||, то надо объединять по ||. Если надо складывать, то надо складывать. Если надо все результаты складывать в один контейнер, то надо складывать.

R>Возможности синхронной обработки тут ни при чём.

При чем, при чем
Если мне в ответ будут подсовывать указатели на объекты разных типов, то максимум, что я смогу сделать -- это сохранить их все как void*. Но что-то мне не нравится такой подход.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Конструктивная критика 4
От: remark Россия http://www.1024cores.net/
Дата: 07.04.06 20:45
Оценка:
Здравствуйте, eao197, Вы писали:


R>>Ну это уже зависит от задачи! Что надо сделать, то и надо реализовать. Если результаты надо объединять по &&, то надо объединять по &&. Если надо объединять по ||, то надо объединять по ||. Если надо складывать, то надо складывать. Если надо все результаты складывать в один контейнер, то надо складывать.

R>>Возможности синхронной обработки тут ни при чём.

E>При чем, при чем

E>Если мне в ответ будут подсовывать указатели на объекты разных типов, то максимум, что я смогу сделать -- это сохранить их все как void*. Но что-то мне не нравится такой подход.


Не понимаю.
Есть определённая задача: несколько кого-то должны что-то обработать и что-то возвратить кому-то обратно. И потом этот кто-то должен что-то сделать со всем, что ему вернули.
Будет ли это происходить асинхронно: все кто обрабытвал сообщение пошлют какие-то данные обратно в сообщениях.
Или синхронно: отправителю сразу вернётся массив каких-то ответов.
Разницы в плане обработки ответов не вижу ну абсолютно никакой. Так или иначе инициатор сообщения окажется с набором каких-то данных. При чём в обоих случаях наборы будут одинаковые.
Если он может что-то сделать с данными в асинхронном варианте, то он уж точно может сделать по крайней мере тоже самое в синхронном варианте.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[7]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 07.04.06 21:05
Оценка:
Здравствуйте, eao197, Вы писали:

R>>Прошу заметить, что DisconnectedState не нужен член Socket socket_


E>А теперь представь, что все агенты в SObjectizer вынуждены менять свои состояния через создание нового объекта-состояния. Агентов могут быть сотни тысяч. А некоторые агенты могут менять свое состояние сотни раз в секунду. И это при том, что реальной очистки ресурсов будут требовать считанные единицы действительно тяжеловесных агентов.


R>>Ну или, например, канал приёма коротких сообщений. Допустим администратор может его включать/отключать (или это происходит автоматически). В активном состоянии каналу может требоваться достаточно много ресурсов: сокет, дополнительный поток, внутрениий буфер, какие-то кэши. А в отключённом состоянии ему это всё не нужно.


E>Ну и в чем проблема? Сокет по любому придется закрывать. Вызовешь у объекта типа CSocket метод close() при смене состояния и все.

E>Поток уснет на каком-нибудь condition variable и никаких ресурсов требовать не будет. Кэши почистятся.
E>Имхо, повторное создание/уничтожение всего этого хозяйства при смене состояния будет гораздо дороже, чем однократное создание его с последующим переводом в standby/ready.

Да. Но всё это приходится делать вручную. Надо об этом помнить. При переходе из такого-то состояния в такое-то надо не забыть разрушить/перевести в такое-то состояние такой-то объект. А при переходе обратно надо не забыть создать объект назад. Надо не забыть, что в таком-то состоянии нельзя обращаться к такому-то члену, т.к. он как бы не актуален в этом состоянии.
Имхо такая замечательная идиома языка с++ как конструктор/деструктор гораздо больше подходят для этой цели, они даже специально сделаны для таких задач.
Если я добавил Socket в Активное_состояние, занчит он автоматически создастся, занчит он автоматически закроется, значит я к нему случайно не обращусь когда не надо.
Если речь идёт об объектах, которых тысячи и миллионы, например короткие сообщения, то никто не мешает в целях оптимизации вынести данные из состояния назад в сам объект. Такой вариант можно предусмотреть отдельно как stateless states.
Если же речь идёт о каких-то "архитектурных" и "больших" агентах системы, которых единицы/десятки, и у которых состояния меняются например только по воле системного администратора, например не чаще чем пару раз в день, то я выбираю для таких агентов логическую стройность и меньшую склонность к ошибкам, чем повышение производительности.





E>>>Кстати, что-то вроде соц.опроса. Представь, что ты присматривался бы к использованию SObjectizer. И увидел бы, что тебе нужно делать описания агентов вот в таком Ruby DSL. Отпугнуло бы это тебя?


R>>Меня лично нет.

R>>Хотя знаю людей, которых всяческие навороты отпугивают — им лучше, что бы всё по старому, по привычному.
R>>Меня гораздо больше отпугивают вещи, которые такие DSL как раз призваны решать — а именно когда в коде есть много вещей, которые хорошо было бы описывать декларативно, но приходится описывать имепративно, да ещё зашивая в описание множество всяких не относящихся к делу вещей — например, описания множества однотипных классов-сущностей, описание структры БД в коде, написание запросов к БД и т.д.
R>>Хотя такой DSL мог бы меня отпугнуть в след. ситуации: DSL в сторонней библиотеке, к которой нет хорошей документации, и я как раз решаю юзать е или нет. Тут DSL может отпугнуть, т.к. всё-таки всё услажняется: т.е. надо помимо кода ещё какие-то файлы писать, как-то дополнительно их обрабатывать и т.д.
R>>А вот если например такой DSL уже используется в проекте, есть примеры, есть знающие люди, налажена компиляция DSL, то тут я только за.

E>Спасибо за высказанное мнение.

E>Надеюсь, что SObjectizer таки относится к библиотекам, для которой есть хорошая документация

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



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.04.06 07:47
Оценка:
Здравствуйте, remark, Вы писали:

R>Да. Но всё это приходится делать вручную. Надо об этом помнить. При переходе из такого-то состояния в такое-то надо не забыть разрушить/перевести в такое-то состояние такой-то объект. А при переходе обратно надо не забыть создать объект назад. Надо не забыть, что в таком-то состоянии нельзя обращаться к такому-то члену, т.к. он как бы не актуален в этом состоянии.

R>Имхо такая замечательная идиома языка с++ как конструктор/деструктор гораздо больше подходят для этой цели, они даже специально сделаны для таких задач.
R>Если я добавил Socket в Активное_состояние, занчит он автоматически создастся, занчит он автоматически закроется, значит я к нему случайно не обращусь когда не надо.
R>Если речь идёт об объектах, которых тысячи и миллионы, например короткие сообщения, то никто не мешает в целях оптимизации вынести данные из состояния назад в сам объект. Такой вариант можно предусмотреть отдельно как stateless states.

Но как быть, если эти агенты не могут быть stateless?

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


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

Да и создавать агента в виде 5-6 классов (классы-состояния + класс-агент) и оформлять это через шаблоны...
namespace traffic_sync {
class initial_state_t : public state_t { ... };
class empty_queue_state_t : public state_t { ... };
class wait_response_state_t : public state_t { ... };
class wait_timeout_state_t : public state_t { ... };

class a_traffic_sync_t : public agent_t<
    initial_state_t,
    empty_queue_state_t,
    wait_response_state_t,
    wait_timeout_state_t >
  {
    ...
  };

}


лично мне не кажется удобным

Да и это настолько далеко от сегодняшней реализации SObjectizer, что рассматривать подобное изменение способа описания/реализации агента, что может рассматриваться только в качестве теоритических изысканий. Может быть для SObjectizer v.6.0

E>>Надеюсь, что SObjectizer таки относится к библиотекам, для которой есть хорошая документация


R>Ну она не то что бы плохая...

R>Но касательно распространённых языков/технологий/инструментов всегда есть книги (желательно на разных языках), есть сообщества, есть промоутинг. Даже я бы наверное сказал, что всё это как раз и делает эти вещи распространёнными.

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



SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: Конструктивная критика 4
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.04.06 07:48
Оценка:
Здравствуйте, remark, Вы писали:

E>>При чем, при чем

E>>Если мне в ответ будут подсовывать указатели на объекты разных типов, то максимум, что я смогу сделать -- это сохранить их все как void*. Но что-то мне не нравится такой подход.

R>Есть определённая задача: несколько кого-то должны что-то обработать и что-то возвратить кому-то обратно. И потом этот кто-то должен что-то сделать со всем, что ему вернули.

R>Будет ли это происходить асинхронно: все кто обрабытвал сообщение пошлют какие-то данные обратно в сообщениях.
R>Или синхронно: отправителю сразу вернётся массив каких-то ответов.
R>Разницы в плане обработки ответов не вижу ну абсолютно никакой.

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

Агент, который инициирует некоторое действие:
void a_initiator_t::evt_initiate()
  {
    ...
    so_4::api::send_msg( some_agent, "msg_action", 0 );
    ...
  }
// И вот в этих событиях он обрабатывает асинхронные ответы в виде типизированных сообщений.
// Можно обратить внимание на то, что внутри обработчика не нужно заботится об определении
// типа сообщения. И вовсе не обязательно, чтобы все msg_*_answer были производными от
// общего корня.
void a_initiator_t::evt_some_answer( const msg_some_answer & cmd ) { ... }
void a_initiator_t::evt_another_answer( const msg_another_answer & cmd ) { ... }
void a_initiator_t::evt_yet_another_answer( const msg_yet_another_answer & cmd ) { ... }

А вот так агенты-исполнители будут отвечать инициатору:
void a_some_actor_t::evt_action( const msg_action & cmd )
  {
    ...
    // Отсылаем ответ.
    so_4::api::send_msg_safely( so_query_name(), "msg_some_answer", new msg_some_answer( ... ) );
  }

void a_another_actor_t::evt_action( const msg_action & cmd )
  {
    ...
    // Отсылаем ответ.
    so_4::api::send_msg_safely( so_query_name(), "msg_another_answer", new msg_another_answer( ... ) );
  }

void a_yet_another_actor_t::evt_action( const msg_action & cmd )
  {
    ...
    // Отсылаем ответ.
    so_4::api::send_msg_safely( so_query_name(), "msg_yet_another_answer", new msg_yet_another_answer( ... ) );
  }


Здесь у инициатора нет необходимости разбираться с типами ответов -- об этом заботится SObjectizer.

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

Во втором случае агенты-исполнители должны явно указать, что они оттдают синхронный ответ:
void a_some_actor_t::evt_action( const so_4::rt::event_data_t & event_data, const msg_action & cmd )
  {
    ...
    // Отсылаем ответ.
    event_data.reply( "msg_some_answer", new msg_some_answer( ... ) );
  }

void a_another_actor_t::evt_action( const so_4::rt::event_data_t & event_data, const msg_action & cmd )
  {
    ...
    // Отсылаем ответ.
    event_data.reply( "msg_another_answer", new msg_another_answer( ... ) );
  }

void a_yet_another_actor_t::evt_action( const so_4::rt::event_data_t & event_data, const msg_action & cmd )
  {
    ...
    // Отсылаем ответ.
    event_data.reply( "msg_yet_another_answer", new msg_yet_another_answer( ... ) );
  }

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

Но как же будет выглядеть само инициирование синхронной операции и обработка ее результата?
Например, вот так:
void a_initiator_t::evt_initiate()
  {
    ...
    so_4::rt::sync_response_t response = so_4::api::sync_msg( some_agent, "msg_action", 0 );
    if( !response.result() && !response.wait( timeout ) )
      {
        // Получили ответ, нужно обрабатывать.
        for( so_4::rt::sync_response_t::const_iterator it = response.begin(), it_end = response.end();
          it != it_end; ++it )
          {
            if( "msg_some_answer" == it->msg_name() )
              process_some_answer( reinterpret_cast< msg_some_answer * >( it->msg_data() ) );
            else if( "msg_another_answer" == it->msg_name() )
              process_another_answer( reinterpret_cast< msg_another_answer * >( it->msg_data() ) );
            else if( "msg_yet_another_answer" == it->msg_name() )
              process_yet_another_answer( reinterpret_cast< msg_yet_another_answer * >( it->msg_data() ) );
          }
      }
    ...
  }

Это примитивный код, его можно облагородить какими-то костылями, например:
    if( !response.result() && !response.wait( timeout ) )
      {
        response.handle( "msg_some_answer", &a_initiator_t::process_some_answer );
        response.handle( "msg_another_answer", &a_initiator_t::process_another_answer );
        response.handle( "msg_yet_another_answer", &a_initiator_t::process_yet_another_answer );
      }


Вот тебе лично какой вариант больше нравится?


По мере написания пришло в голову, что можно сделать вот так... Перед отправкой синхронного запроса можно перечислить, какие сообщения ожидаются в ответ и сразу же указать их обработчиков:
void a_initiator_t::evt_initiate()
  {
    ...
    so_4::rt::sync_request_t request;
    request.add_handler( "msg_some_answer", &a_initiator_t::process_some_answer );
    request.add_handler( "msg_another_answer", &a_initiator_t::process_another_answer );
    request.add_handler( "msg_yet_another_answer", &a_initiator_t::process_yet_another_answer );
    if( !request.send( some_agent, "msg_action" ) && !request.wait( timeout ) )
      request.handle();
    else
      ...
  }

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 08.04.06 14:54
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Да. Но всё это приходится делать вручную. Надо об этом помнить. При переходе из такого-то состояния в такое-то надо не забыть разрушить/перевести в такое-то состояние такой-то объект. А при переходе обратно надо не забыть создать объект назад. Надо не забыть, что в таком-то состоянии нельзя обращаться к такому-то члену, т.к. он как бы не актуален в этом состоянии.

R>>Имхо такая замечательная идиома языка с++ как конструктор/деструктор гораздо больше подходят для этой цели, они даже специально сделаны для таких задач.
R>>Если я добавил Socket в Активное_состояние, занчит он автоматически создастся, занчит он автоматически закроется, значит я к нему случайно не обращусь когда не надо.
R>>Если речь идёт об объектах, которых тысячи и миллионы, например короткие сообщения, то никто не мешает в целях оптимизации вынести данные из состояния назад в сам объект. Такой вариант можно предусмотреть отдельно как stateless states.

E>Но как быть, если эти агенты не могут быть stateless?


Нет, не агент stateless, а state stateless





E>>>Надеюсь, что SObjectizer таки относится к библиотекам, для которой есть хорошая документация


R>>Ну она не то что бы плохая...

R>>Но касательно распространённых языков/технологий/инструментов всегда есть книги (желательно на разных языках), есть сообщества, есть промоутинг. Даже я бы наверное сказал, что всё это как раз и делает эти вещи распространёнными.

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


Надо на большем кол-ве форумов. Может с каждого по паре энтузиастов и заинтересованных лиц и будет.



E>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.04.06 15:20
Оценка:
Здравствуйте, remark, Вы писали:

E>>Но как быть, если эти агенты не могут быть stateless?


R>Нет, не агент stateless, а state stateless


stateless state

Смешно. С учетом того, что состояние определяет поведение, а не структуру (данные) объекта.

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


R>Надо на большем кол-ве форумов.


Каких, например?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 08.04.06 23:33
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


E>>>Но как быть, если эти агенты не могут быть stateless?


R>>Нет, не агент stateless, а state stateless


E>stateless state


E>Смешно. С учетом того, что состояние определяет поведение, а не структуру (данные) объекта.


Я надеюсь, ты имеешь в виду "что состояние определяет поведение, а не структуру (данные) объекта в SObjectizer", а не вообще. Я предлагаю сделать возможность иметь более традиционный вариант, когда состояние определяет и данные (см. например паттерн State GOF). Мне более привычен традиционный ОО подход, когда поведение объединяется с данными нужными для этого поведения. В конце концов как может быть поведение без данных.




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


R>>Надо на большем кол-ве форумов.


E>Каких, например?


Не знаю. Но должны же быть какие-то ещё


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[12]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.04.06 05:59
Оценка:
Здравствуйте, remark, Вы писали:

E>>Смешно. С учетом того, что состояние определяет поведение, а не структуру (данные) объекта.


R>Я надеюсь, ты имеешь в виду "что состояние определяет поведение, а не структуру (данные) объекта в SObjectizer", а не вообще.


Да. Именно в SObjectizer
Это ведь тема, посвященная SObjectizer


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: SObjectizer: I Love This Game!
От: S4  
Дата: 10.04.06 11:51
Оценка: 13 (1)
Здравствуйте, eao197, Вы писали:

Имхо, самое полезное, если будет порт на c++/cli. И работы меньше, чем переписывать на c# и все преимущетсва .net использовать можно.

E>Вот это роль SObjectizer как до сих пор видел ее я. То, что SObjectizer написан на C++ -- это следствие истории его развития ("Все мы жертвы цепи нелепых случайностей" (C) К.Вонегут). Если в SObjectizer-е будет заинтересованность, то он может быть реализован и на других языках (не сразу, конечно). Мне хотелось бы понять, будет ли в этом потребность (т.е. заинтересованность читателей журнала и форума) и, если будет, то к какому языку прежде всего нужно будет присмотреться.
Re[13]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 30.04.06 21:53
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


E>>>Смешно. С учетом того, что состояние определяет поведение, а не структуру (данные) объекта.


R>>Я надеюсь, ты имеешь в виду "что состояние определяет поведение, а не структуру (данные) объекта в SObjectizer", а не вообще.


E>Да. Именно в SObjectizer

E>Это ведь тема, посвященная SObjectizer


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

Я так понял, что SObjectizer достаточно лёгкий. Т.е. его можно поднять только что бы организовать взаимодействие между двумя агентами. А сколько уйдёт времени и кода на то, что бы прикрутить SObjectizer к проекту и организовать взаимодействие между 2 агентами?

По поводу перехода SObjectizer на другие языки. здесь
Автор: vdimas
Дата: 14.02.06
было очень плодовитое обсуждение. Я сейчас тоже склоняюсь больше в сторону C#. Многие вещи, которые на с++ представляют серьёзную проблемы, там бы делались настолько элементарно...
Например, сериализация, в С# надо написать ровно 0 строк кода, что бы обеспечить сериализацию. А это важный аспект для такой системы как SObjectizer.
Причём для сериализации там есть несколько сериализаторов. Т.е. внутри приложения можно использовать бинарный, что обеспечит скорость. А вне приложения можно использовать XML-сериализатор. Тогда уже можно обеспечить взаимодействие и с Java, и с чем угодно.
Есть только одно но, С# жестко привяжет SObjectizer к Windows и M$... Меня лично это не пугает, но тем не менее.
Там же есть такая крутая вещь как IAsyncResult, которая уже здесь упоминалась. Она красиво решит проблему синхронного выполнения. И можно сделать идентификацию сообщений всё-таки типобезопасной, а не на основе строковых имен, причём без ущерба там вещах, о которых ты писал, как о причинах использования строковых имён.

Вобщем, если SObjectizer перевести на С#, то придётся наверное процентов 90 кода удалить по причине ненужности. Я, когда начал писать на С#, довольно скоро выработал такую привычку "если хочешь, что-то реализовать, то вначале открой help по .net, скорее всего ты там уже найдёшь то, что ты хочешь реализовать"

Хотя сам я сейчас профессионально работаю (всё ещё ) с с++, т.ч. интерес более из интереса, чем профессиональный.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[14]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.05.06 06:29
Оценка: 7 (1)
Здравствуйте, remark, Вы писали:

R>Я так понял, что SObjectizer достаточно лёгкий. Т.е. его можно поднять только что бы организовать взаимодействие между двумя агентами. А сколько уйдёт времени и кода на то, что бы прикрутить SObjectizer к проекту и организовать взаимодействие между 2 агентами?


Время зависит от уровня знания SObjectizer и степени сложности агентов, с которыми нужно будет работать.
Что касается кода -- то это зависит от сложности агентов. Необходимо будет реализовать:
* запуск SObjectizer Run-Time (если речь идет не о полностью SObjectizer-приложении, то делать это нужно на контексте отдельной нити, т.к. она окажется заблокированной). Например, вот так:
//
// Нить, на которой будет происходить запуск SObjectizer-а
//
ACE_THR_FUNC_RETURN
sobjectizer_thread( void * )
{
    std::auto_ptr< so_4::timer_thread::timer_thread_t >
        timer_ptr( so_4::timer_thread::simple::create_timer_thread() );

    std::auto_ptr< so_4::rt::dispatcher_t >
        disp_ptr( so_4::disp::active_obj::create_disp( *timer_ptr ) );

    so_4::ret_code_t rc = so_4::api::start( *disp_ptr, 0 );
    if( rc )
    {
        std::cerr << "start: " << rc << std::endl;
    }

    return 0;
}

int
main( int argc, char ** argv )
{
    if( 2 == argc )
    {
        ACE_Thread_Manager::instance()->spawn( &sobjectizer_thread );

        // Засыпаем, чтобы дать стартовать SObjectizer.
        // Это самый простой способ синхронизации с sobj_thread_t.
        ACE_OS::sleep( 1 );
...


* реализации агентов и описания агентов для SObjectizer. Собственно, реализация агента -- это обычный C++ класс с определением и реализацией. А описание агента для SObjectizer может выглядеть так:
SOL4_CLASS_START( a_cln_t )

    SOL4_MSG_START( msg_send_request,
        a_cln_t::msg_send_request )
    SOL4_MSG_FINISH()

    SOL4_EVENT( evt_start )

    SOL4_EVENT_STC(
        evt_send_request,
        a_cln_t::msg_send_request )

    SOL4_EVENT_STC(
        evt_server_reply,
        c1i_t::msg_reply )

    SOL4_STATE_START( st_normal )
        SOL4_STATE_EVENT( evt_start )
        SOL4_STATE_EVENT( evt_send_request )
        SOL4_STATE_EVENT( evt_server_reply )
    SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()


Это самая избыточная часть описания для SObjectizer.

* организации подписки агентов (реализация методов so_on_subscription()).

Резюмируя: не так лаконично, как можно было бы сделать в Lisp, Ruby или Nemerle. Но и довольно просто, чтобы писать просто руками, без IDE и Wizard-ов, не испытывая при этом трудностей.

Приведенные фрагменты кода взяты из примера filter/c1.cpp


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.05.06 07:04
Оценка:
Здравствуйте, remark, Вы писали:

R>По поводу перехода SObjectizer на другие языки. здесь
Автор: vdimas
Дата: 14.02.06
было очень плодовитое обсуждение. Я сейчас тоже склоняюсь больше в сторону C#. Многие вещи, которые на с++ представляют серьёзную проблемы, там бы делались настолько элементарно...


А я сейчас в сторону C# уже не склоняюсь

R>Например, сериализация, в С# надо написать ровно 0 строк кода, что бы обеспечить сериализацию. А это важный аспект для такой системы как SObjectizer.


Для сериализации в SObjectizer используется ObjESSty
Автор: eao197
Дата: 24.01.05
, так что сериализация сложных (не циклических структур) в SObjectizer выполняется без проблем. Да еще в ObjESSty заложена возможность поддержки прозрачной расширяемости объектов, что очень удобно на практике при сопровождении распределенных приложений.

R>Причём для сериализации там есть несколько сериализаторов. Т.е. внутри приложения можно использовать бинарный, что обеспечит скорость. А вне приложения можно использовать XML-сериализатор. Тогда уже можно обеспечить взаимодействие и с Java, и с чем угодно.


Проблема взаимодействия SObjectizer с приложениями на других языках заключается не столько в способе сериализации данных, сколько в необходимости поддержки SOP. Либо внешенее приложение должно поддерживать SOP-соединения и соответствующую логику, либо же в SObjectizer нужно делать другие типы входов (например, на основе XML-RPC).

R>Есть только одно но, С# жестко привяжет SObjectizer к Windows и M$... Меня лично это не пугает, но тем не менее.


А меня пугает

R>Там же есть такая крутая вещь как IAsyncResult, которая уже здесь упоминалась. Она красиво решит проблему синхронного выполнения. И можно сделать идентификацию сообщений всё-таки типобезопасной, а не на основе строковых имен, причём без ущерба там вещах, о которых ты писал, как о причинах использования строковых имён.


R>Вобщем, если SObjectizer перевести на С#, то придётся наверное процентов 90 кода удалить по причине ненужности. Я, когда начал писать на С#, довольно скоро выработал такую привычку "если хочешь, что-то реализовать, то вначале открой help по .net, скорее всего ты там уже найдёшь то, что ты хочешь реализовать"


За последнее время я прикинул возможности портирования SObjectizer на несколько разных языков: D, Java, Scala (у него есть интероперабильность с JDK), Nemerle, Ruby и даже Eiffel (кстати, очень приличный язык, жалко, что его маркетологи загубили). И пришел к выводу, что вопрос о том, что в конкретном языке/платформе будет удобно для SObjectizer, возможно, даже не самый интересный и важный. От языка/платформы SObjectizer нужна, во-первых, большая библиотека (вроде JDK, .NET Framework, Ruby Library или ACE в C++). По этой причине D и Eiffel, к сожалению пока пролетают. Во-вторых, хотелось бы, чтобы язык предоставлял возможность для реализации DSL, необходимых SObjectizer. Здесь лидерами являются Nemerle и Ruby.

Но более важный вопрос в том, насколько нужен будет сам SObjectizer на конкретном языке/платформе. Ну например, будет SObjectizer for Java. Кому-нибудь он вообще понадобится? Аналогичный вопрос и по поводу SObjectizer for C# (Nemerle, Scala). Складывается впечатление, что чем более богатый Framework предоставляет платформа, тем менее нужен для нее SObjectizer. Взать тот же IAsyncResult в .NET, а так же развитые средства для организации удаленного взаимодействия в .NET (либо в JDK). Ну и зачем там спрашивается еще и SObjectizer? Может статься, что на мейнстримовых платформах SObjectizer будет нужен еще меньшему количеству разработчиков, чем в случае C++/Ruby/D/Eiffel. Так же не нужно забывать о таком феномене, что мейнстримовые разработчики имеют склонность использовать мейнстримовые же инструменты. SObjectizer таким инструментом никогда не станет

А вот если посмотреть на менее признаные языки (в первую очередь C++, а так же Ruby и D), то окажется, что в них SObjectizer предлагает разработчику часть инструментов, которые есть .NET/JDK, но нет в C++/Ruby/D. Поэтому для таких языков SObjectizer может стать более востребованным.

Ну и один из самых важных факторов: SObjectizer сейчас активно используется только в нашей компании (пока, я надеюсь, т.к. статистика SourceForge свидетельствует о наличии интереса к SObjectizer). А у нас разработка идет на C++ и Java (J2EE). Причем Java проекты не нуждаются в порте SObjectizer на Java. Посему просто нет причин, чтобы сейчас нам портировать SObjectizer на C# или Java. Есть желание сделать порт SObjectizer на Ruby, чтобы некоторые инструменты реализовывать быстрее (и делать их компактнее).

Но, если у кого-то будет серьезная заинтересованность в SObjectizer для C# или Java, то это дело можно будет реализовать (либо в выпуске соответствующего проекта под заказ ), либо в виде ветви OpenSource-проекта.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[15]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 01.05.06 21:28
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Я так понял, что SObjectizer достаточно лёгкий. Т.е. его можно поднять только что бы организовать взаимодействие между двумя агентами. А сколько уйдёт времени и кода на то, что бы прикрутить SObjectizer к проекту и организовать взаимодействие между 2 агентами?


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


[skip]

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


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[15]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 01.05.06 21:52
Оценка:
Здравствуйте, eao197, Вы писали:

E>Для сериализации в SObjectizer используется ObjESSty
Автор: eao197
Дата: 24.01.05
, так что сериализация сложных (не циклических структур) в SObjectizer выполняется без проблем. Да еще в ObjESSty заложена возможность поддержки прозрачной расширяемости объектов, что очень удобно на практике при сопровождении распределенных приложений.


Я синтаксис его использования не смотрел, но думаю, что ObjESSty серьёзно сливает в этом плане встроенным в С# возможностям.



E>Проблема взаимодействия SObjectizer с приложениями на других языках заключается не столько в способе сериализации данных, сколько в необходимости поддержки SOP. Либо внешенее приложение должно поддерживать SOP-соединения и соответствующую логику, либо же в SObjectizer нужно делать другие типы входов (например, на основе XML-RPC).


Вот это, я думаю, перспективно... Но с учтётом того, что SObjectizer применяется только в одной компании, наверное, пока не надо




E>Во-вторых, хотелось бы, чтобы язык предоставлял возможность для реализации DSL, необходимых SObjectizer. Здесь лидерами являются Nemerle и Ruby.


Опять скажу по поводу С#. DSL на нём делать нельзя. Но там есть аттрибуты, которые могут дать достаточно "приятный" синтаксис описания.
Например, сообщения — ты не хотел их наследовать от одного класса. Можно их просто помечать аттрибутом:

[Message]
class MyMessage
{...}


Аналогично — агенты. Плюс ещё можно использовать параметры в аттрибутах:

[Agent (Threading = Active, Visible = Global)]
class Queue
{
  [MessageHandler(SomeMessage)]
  public void OnSomeMessage(SomeMessage msg);
}


А с применением рефлекшана, от падает необходимость в повторном описании всех полей сообщения. Т.е. достаточно его просто пометить аттрибутом.



E>Но более важный вопрос в том, насколько нужен будет сам SObjectizer на конкретном языке/платформе. Ну например, будет SObjectizer for Java. Кому-нибудь он вообще понадобится? Аналогичный вопрос и по поводу SObjectizer for C# (Nemerle, Scala). Складывается впечатление, что чем более богатый Framework предоставляет платформа, тем менее нужен для нее SObjectizer. Взать тот же IAsyncResult в .NET, а так же развитые средства для организации удаленного взаимодействия в .NET (либо в JDK). Ну и зачем там спрашивается еще и SObjectizer? Может статься, что на мейнстримовых платформах SObjectizer будет нужен еще меньшему количеству разработчиков, чем в случае C++/Ruby/D/Eiffel. Так же не нужно забывать о таком феномене, что мейнстримовые разработчики имеют склонность использовать мейнстримовые же инструменты. SObjectizer таким инструментом никогда не станет


E>А вот если посмотреть на менее признаные языки (в первую очередь C++, а так же Ruby и D), то окажется, что в них SObjectizer предлагает разработчику часть инструментов, которые есть .NET/JDK, но нет в C++/Ruby/D. Поэтому для таких языков SObjectizer может стать более востребованным.


на менее признаные языки — в первую очередь C++


Я думаю, что такой фреймворк, как SObjectizer, мог бы быть полезным для C# и Java.
Мог бы потому что там есть много полезных вещей — рефлекшн, IAsyncResult, потоки, сокеты, но там нет того, что могло бы объединить всё это в законченный фрейморк для создания определённого круга приложений (многопоточные серверные приложения, не самые тривиальные толстые клиенты и т.д.)
Нет базового класса, от которых я мог бы отнаследовать агента, нет ядра распределения сообщений и т.д.

Т.е. если сейчас я сяду делать приложение на С# то, мне придётся всё это изобретать самому. Конечно из более высокоуровневых деталей сем в с++, но всё же.
Я говорю о таком фреймворке как WinForms (для gui толстых клиентов) или asp.net (для web приложений)

В общем, я бы не сказал, что он там не нужен. Просто может необходимость в нём не так видна как в с++, т.к. в распоряжении всё-таки более высокоуровневые вещи, и не приходится всё это делать с нуля как в с++. А так собственно необходимость не меньше.
Другой вопрос, что на C#/Java сейчас делают меньше приложений такого класса, в которых нужен SObjectizer. Понятно, что в asp.net SObjectizer не нужен. Мне кажется, что бОльшую часть приложений такого класса сейчас делают всё же именно на С++.




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: SObjectizer: I Love This Game!
От: Mamut Швеция http://dmitriid.com
Дата: 09.05.06 07:15
Оценка:
Решил задать вопрос здесь, а не в @linux
Автор: Mamut
Дата: 03.05.06
.

Собственно, интересует два вопроса:

1. Насколько сложные сообщения можно создавать для SObjectizer'a. То есть интересует вопрос впихивания, например, списков да и вообще контейнеров из STL.

2. И главный вопрос — есть ли возможность прикрутить свой собственный сериализатор/десериализатор. Или появится ли такая возможность в будущем?
... << RSDN@Home 1.2.0 alpha rev. 647>> ... <<Max Rabe — Let's Talk about ...>> ...


dmitriid.comGitHubLinkedIn
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.05.06 08:24
Оценка: 18 (1)
Здравствуйте, Mamut, Вы писали:

M>Решил задать вопрос здесь, а не в @linux
Автор: Mamut
Дата: 03.05.06
.


И это правильно

M>1. Насколько сложные сообщения можно создавать для SObjectizer'a. То есть интересует вопрос впихивания, например, списков да и вообще контейнеров из STL.


Если сообщение не будет выходить за пределы процесса, то на структуру сообщения вообще практически никаких ограничений нет. Хоть STL-контейнеры, хоть Boost-, хоть Qt- и т.д.

Если же сообщение принадлежит глобальному агенту и должно ходить по SOP, то допускаются поля примитивных типов (char, short, int, float, double, std::string) и сериализуемых средствами ObjESSty
Автор: eao197
Дата: 24.01.05
типов (а там поддерживаются многие STL контейнеры, указатели). Так же ObjESSty позволяет прикручивать собственную сериализацию для произвольных типов (например, так в ObjESSty сделана сериализация типа ACE_Date_Time).

M>2. И главный вопрос — есть ли возможность прикрутить свой собственный сериализатор/десериализатор. Или появится ли такая возможность в будущем?


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: SObjectizer: I Love This Game!
От: Mamut Швеция http://dmitriid.com
Дата: 09.05.06 09:18
Оценка:
M>>2. И главный вопрос — есть ли возможность прикрутить свой собственный сериализатор/десериализатор. Или появится ли такая возможность в будущем?

E>В принципе, можно. Хотя в SObjectizer-е пока не заложено возможности использования сторонних сериализаторов для SOP. Что касается появления такой возможности в будущем, то все зависит от спроса

E>Если будет очень нужно, то можно будет и сделать.

Нужно-нужно

Вернее, было бы неплохо Я сейчас, правда, с ходу не придумаю, но, например, для "моментальной" интеграции с уже существующими системами.
... << RSDN@Home 1.2.0 alpha rev. 647>> ... <<Max Rabe — Let's Talk about ...>> ...


dmitriid.comGitHubLinkedIn
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.05.06 10:15
Оценка:
Здравствуйте, Mamut, Вы писали:

E>>Если будет очень нужно, то можно будет и сделать.


M>Нужно-нужно


M>Вернее, было бы неплохо Я сейчас, правда, с ходу не придумаю, но, например, для "моментальной" интеграции с уже существующими системами.


А какие именно системы сериализации интересуют в первую очередь?
И идет ли речь об интероперабельности только с C++ или другими языками? (Просто у меня есть желание сделать поддержку ObjESSty в Ruby, а затем и порт SObjectizer на Ruby. В этом случае другие системы сериализации не смогут с SObjectizerOnRuby взаимодействовать).



Дмитрий, извини за офтопик, но хотел спросить про @linux. А вариант реализации @linux на Erlang рассматривался (ты же им интересовался, вроде)? Имхо, нарисованная Sheridan структура вполне бы легла на Erlang. Да и такая идея могла бы найти своих сторонников из числа участников "Декларативного программирования"


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game!
От: Mamut Швеция http://dmitriid.com
Дата: 09.05.06 11:01
Оценка: 12 (1)
E>А какие именно системы сериализации интересуют в первую очередь?
E>И идет ли речь об интероперабельности только с C++ или другими языками? (Просто у меня есть желание сделать поддержку ObjESSty в Ruby, а затем и порт SObjectizer на Ruby. В этом случае другие системы сериализации не смогут с SObjectizerOnRuby взаимодействовать).

Наверное, JSON (особенно в свете Comments.Planning-Protocol (в самом низу)). Я также понимаю, что и какой-нить ASN.1 тоже not out of the question. И вообще, мало ли народ собственных протоколов придумывает

То есть если бы была возможность сделать типа registerSerializer(mySerializer), где mySerializer — класс, принимающий на входе некий so_message, а на выходе — свой формат (JSON, XML, DCOP, SOAP, свой протокол), было бы здорово.

Ну и это бы позволило общение и сдругими языками тоже (через тот же JSON, например)

E>

E>Дмитрий, извини за офтопик, но хотел спросить про @linux. А вариант реализации @linux на Erlang рассматривался (ты же им интересовался, вроде)? Имхо, нарисованная Sheridan структура вполне бы легла на Erlang. Да и такая идея могла бы найти своих сторонников из числа участников "Декларативного программирования"



У меня уже месяца четыре как мечта идиота — серверную часть на Эрланге реализовать Но времени даже обучится Эрлангу нет (пока что слегка поковырял Мнезию и xmerl).

Дур... Умные люди действительно мыслят одинаково
... << RSDN@Home 1.2.0 alpha rev. 647>> ... <<Max Rabe — Let's Talk about ...>> ...


dmitriid.comGitHubLinkedIn
Re[6]: SObjectizer: I Love This Game!
От: Зверёк Харьковский  
Дата: 09.05.06 11:14
Оценка: +1
Здравствуйте, Mamut, Вы писали:

E>>А какие именно системы сериализации интересуют в первую очередь?

E>>И идет ли речь об интероперабельности только с C++ или другими языками? (Просто у меня есть желание сделать поддержку ObjESSty в Ruby, а затем и порт SObjectizer на Ruby. В этом случае другие системы сериализации не смогут с SObjectizerOnRuby взаимодействовать).

M>Наверное, JSON (особенно в свете Comments.Planning-Protocol (в самом низу)). Я также понимаю, что и какой-нить ASN.1 тоже not out of the question. И вообще, мало ли народ собственных протоколов придумывает


В копилочку: есть еще такая отличная штука как YAML — как JSON, только круче
FAQ — це мiй ай-кью!
Re[7]: SObjectizer: I Love This Game!
От: Mamut Швеция http://dmitriid.com
Дата: 09.05.06 12:04
Оценка:
M>>Наверное, JSON (особенно в свете Comments.Planning-Protocol (в самом низу)). Я также понимаю, что и какой-нить ASN.1 тоже not out of the question. И вообще, мало ли народ собственных протоколов придумывает

ЗХ>В копилочку: есть еще такая отличная штука как YAML — как JSON, только круче


Ну или YAML, тем более что YAML is JSON
... << RSDN@Home 1.2.0 alpha rev. 647>> ... <<Max Rabe — Let's Talk about ...>> ...


dmitriid.comGitHubLinkedIn
Re[6]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.05.06 19:21
Оценка: 9 (1)
Здравствуйте, Mamut, Вы писали:

E>>А какие именно системы сериализации интересуют в первую очередь?


M>Наверное, JSON (особенно в свете Comments.Planning-Protocol (в самом низу)). Я также понимаю, что и какой-нить ASN.1 тоже not out of the question. И вообще, мало ли народ собственных протоколов придумывает


Вообще-то ты перечислил форматы, а я спрашивал про библиотеки/фреймворки, которые могут эти или другие форматы поддерживать. Вроде Boost.Serialization или s11n.net. Все-таки, к хорошему быстро привыкаешь и, когда в программе есть возможность манипулировать просто прикладными объектами, то о лежащем в низу протоколе уже не думаешь. Например, представь себе, что система сериализации позволяет тебе работать такими объектами:
class Message_Info {
  public :
    Message_Id get_id() const;
    User_Id author() const;
    Date_Time sent_at() const;
    ...
};

class Forum_Topic_Info {
  public :
    Forum_Id get_id() const;
    std::string subject() const;
    Date_Time created_at() const;
    ...
};

class Forum_Topic_Updates {
  public :
    std::list< Message_Info >
    updates() const;
    ...
};

class Last_Changes {
  public :
    std::map< Forum_Topic_Info, Forum_Topic_Updates >
    changes() const;
    ...
};

то уже без особой разницы, в какой поток байт объекты этих типов преобразуются. Важно то, если ли возможность в программе просто передавать эти объекты куда-либо, или же нужно куда-то что-то преобразовывать. Системы сериализации вроде ObjESSty, Boost.Serialization, s11n как раз снимает с разработчика необходимость думать о тонкостях результирующего формата.

<offtopic>
В обсуждении по данной тобой ссылке мне больше всего понравилась фраза:

Опять же настоятельно требую посмотреть на ICE или другие, уже готовые реализации протоколов

+1
Очень правильные слова.
</offtopic>

M>То есть если бы была возможность сделать типа registerSerializer(mySerializer), где mySerializer — класс, принимающий на входе некий so_message, а на выходе — свой формат (JSON, XML, DCOP, SOAP, свой протокол), было бы здорово.


Тут напрашивается аналогия с Multi Agent System (http://www.fipa.org). Там выделяются понятия Message, Encoding-Service, Transport-Message, Transport. Message-Transport-Service. Что позволяет одно и то же сообщение (объект Message) преобразовать с помощью разных форматов (через Encoding-Service) в разные транспортные объекты (Transport-Message), которые передаются через различные Message-Transpore-Service.

В SObjectizer до сих пор была очень легковесная (хотя и жесткая) схема -- один тип формата, один протокол, один тип транспорта (TCP, хотя можно приспособить и другие stream-oriented транспорты, вроде pipes). Для того, чтобы внедрить поддержку разных форматов в SObjectizer придется вводить подобное разделение обязанностей. В результате тот же FIPA и получится, только доморощенный

Естественно, если в этом будет необходимость, можно будет докрутить SObjectizer и до такой крутизны

M>Ну и это бы позволило общение и сдругими языками тоже (через тот же JSON, например)


С другими языками проблема не только в том, чтобы уметь объект-сообщение десериализовать. Нужно еще уметь соединения с SObjectizer приложениями устанавливать, процедуру handshake проходить, соединения в работоспособности проверять, обмениваться данными. В таких условиях, имхо, проще для конкретного языка сделать порт части SObjectizer (хотя бы поддержки транспорта и SOP) и ObjESSty (сериализацию). А тогда уже особого смысла в других форматах может и не быть

M>Дур... Умные люди действительно мыслят одинаково



SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: SObjectizer: I Love This Game!
От: Mamut Швеция http://dmitriid.com
Дата: 09.05.06 21:23
Оценка: 12 (1)
E>>>А какие именно системы сериализации интересуют в первую очередь?

M>>Наверное, JSON (особенно в свете Comments.Planning-Protocol (в самом низу)). Я также понимаю, что и какой-нить ASN.1 тоже not out of the question. И вообще, мало ли народ собственных протоколов придумывает


E>Вообще-то ты перечислил форматы, а я спрашивал про библиотеки/фреймворки, которые могут эти или другие форматы поддерживать. Вроде Boost.Serialization или s11n.net.


Ааа... Хмм... Так я навскидку и не придумаю... В голову лезет всякая фигня типа веб-сервисов и ЯваСкрипта. Или какой-нибудь Jabber (XMPP) или даже Libjingle. Из того, что действительно могло бы понадобиться — разве что действительно общение с программами, написаными на других языках (хотя бы с тем же эрлангом, например ).

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

E>

E>

E>то уже без особой разницы, в какой поток байт объекты этих типов преобразуются. Важно то, если ли возможность в программе просто передавать эти объекты куда-либо, или же нужно куда-то что-то преобразовывать. Системы сериализации вроде ObjESSty, Boost.Serialization, s11n как раз снимает с разработчика необходимость думать о тонкостях результирующего формата.

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

M>>То есть если бы была возможность сделать типа registerSerializer(mySerializer), где mySerializer — класс, принимающий на входе некий so_message, а на выходе — свой формат (JSON, XML, DCOP, SOAP, свой протокол), было бы здорово.


E>Тут напрашивается аналогия с Multi Agent System (http://www.fipa.org). Там выделяются понятия Message, Encoding-Service, Transport-Message, Transport. Message-Transport-Service. Что позволяет одно и то же сообщение (объект Message) преобразовать с помощью разных форматов (через Encoding-Service) в разные транспортные объекты (Transport-Message), которые передаются через различные Message-Transpore-Service.


E>В SObjectizer до сих пор была очень легковесная (хотя и жесткая) схема -- один тип формата, один протокол, один тип транспорта (TCP, хотя можно приспособить и другие stream-oriented транспорты, вроде pipes). Для того, чтобы внедрить поддержку разных форматов в SObjectizer придется вводить подобное разделение обязанностей. В результате тот же FIPA и получится, только доморощенный


Зато готовый, который пощупать руками можно. А то от ФИПЫ ничего, кроме спецификаций, не дождешься

E>Естественно, если в этом будет необходимость, можно будет докрутить SObjectizer и до такой крутизны


Ага, ага

M>>Ну и это бы позволило общение и сдругими языками тоже (через тот же JSON, например)


E>С другими языками проблема не только в том, чтобы уметь объект-сообщение десериализовать. Нужно еще уметь соединения с SObjectizer приложениями устанавливать, процедуру handshake проходить, соединения в работоспособности проверять, обмениваться данными. В таких условиях, имхо, проще для конкретного языка сделать порт части SObjectizer (хотя бы поддержки транспорта и SOP) и ObjESSty (сериализацию). А тогда уже особого смысла в других форматах может и не быть


Предположим такой маньячный вариант: Клиент подсоединяется к некой программе, как к веб-серверу. Все, что у клиента есть, — это веб-интерфейс и ЯваСкрипт (он же Аякс). ЯваСкрипт, соответственно, работает через JSON, потому что так легче. На серваке все равно придется писать прослойку JSON <-> SObjectizer, потому что реализовать SOP и сериализацию, наверное, можно и на ЯваСкрипте, но лучше не надо

Сюда же можно отнести, наверное, любые приложения, используюшие что-либо из этого списка. Да и мало ли Вон, в @линух тоже свой протокол собираются писать Я, правда, не дамся


dmitriid.comGitHubLinkedIn
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.05.06 12:51
Оценка: 16 (1)
Здравствуйте, Mamut:

<...написанное ранее внимательно прочитано...>

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

Возьмем, к примеру создание SOP соединений. После создания физического канала стороны должны провести процедуру handshake и произвести обмен фильтрами. После этого в канале начнут циркулировать сообщения агентов. При этом сообщение идет не как RPC-like обмен запрос-ответ, а как поток PDU, в каждом из которых находится свое сообщение. Далее, в каждом сообщении кроме самих полей сообщения передается метаинформация, как то: имя агента-владельца, имя сообщения, имя получателя, задержка перед отправкой.

Все это я говорю к тому, что:
* некоторые типы протоколов (например, XML-PRC, SOAP) не ложатся просто так на текущую модель SOP. Поддержка таких протоколов прозрачным для SObjectizer-агентов образом потребует создания неких шлюзов, имитирующих наличие SOP-каналов, их фильтры, их живучесть и пр.;
* поскольку для SOP нужна метаинформация к каждому сообщению, не получится приспосабливать какой-то готовый прикладной протокол для взаимодействия с SObjectizer, поскольку в этом случае в элементах прикладного протокола не предусмотрена метаинформация для SObjectizer;
* сторона, обращающаяся к SObjectizer должна понимать, что взаимодействие асинхронное и на отсланное сообщение не будет мнгновенного ответа. Соответственно, придется вместо привычного RPC-line стиля взаимодействия запрос-ответ, использовать у себя что-то другое;
* если SObjectizer сможет поддерживать набор разных внешних протоколов и форматов (как то JSON, YAML, XML и др.), то тогда встанет вопрос о том, как одно и то же сообщение сериализовать в каждый из форматов. Т.е. придется двигаться в сторону FIPA с ее content-language, encoding-service и пр.

Самый главный момент в том, что нужно понимать, если в SObjectizer отсылается какое-то сообщение Last_Changes, то просто по семантике агентно-ориентированного взаимодействия оно не может придти в том же самом виде в какое-то Java-приложение. Если только это Java-приложение не ожидало вместо Last_Changes сообщение SobjAgentMessage, в котором Last_Changes было бы всего лишь полем messagePayload.

Поэтому мне кажется, что если необходимо обеспечить прозрачное взаимодействие SObjectizer с другими приложениями, то это нужно делать не на основе адаптации SOP к другим протоколам, а на основе уменьшения степень прозрачности. Например, SOP подразумевает, что есть какой-то глобальный агент и что можно отослать какое-то сообщение этого агента. И SObjectizer сам разошлет это сообщение во все имеющиеся коммуникационные каналы, которые пропускают это сообщение через свои фильтры. Вместо этого лучше, имхо, выделить конкретные прикладные сообщения (которые будут ходить по какому-нибудь XML-RPC или SOAP) в сообщения конкретного агента. А сам этот агент будет заниматься их получением, преобразованием в конкретный протокол и пр.

Что-то подобное мы у себя проделывали с подключением к SObjectizer приложению SOAP-клиентов (через gSOAP обрабатывались входящие запросы, которые как SObjectizer сообщения отсылались во внутрь системы на обработку) и при подключении SObjectizer-приложения наружу через XML-RPC.

Т.е. мне кажется более перспективным не натягивание SOP надругие типы транспорта, а на создание библиотек шлюзов между SObjectizer и другими приложениями через различные виды транспорта.

Вот как-то так. Сумбурно получилось. Если смогу сформулировать точнее, то допишу.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: SObjectizer: I Love This Game!
От: Mamut Швеция http://dmitriid.com
Дата: 10.05.06 14:05
Оценка:
E>Вот как-то так. Сумбурно получилось. Если смогу сформулировать точнее, то допишу.

Ага, я понял. Буду думать
... << RSDN@Home 1.2.0 alpha rev. 647>> ... <<Max Rabe — Let's Talk about ...>> ...


dmitriid.comGitHubLinkedIn
Re: SObjectizer: I Love This Game!
От: Аноним  
Дата: 22.05.06 11:49
Оценка:
Подробно-подробно не читал, но хочется вкратце знать, чем это отличается от какого-нибудь MoM типа SonicMQ или TIBCO Randevouz?
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 22.05.06 12:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Подробно-подробно не читал, но хочется вкратце знать, чем это отличается от какого-нибудь MoM типа SonicMQ или TIBCO Randevouz?



Мне тоже
Не хватает времени на то, чтобы внимательно изучать все ссылки, которые мне присылают после публикации статьи о SObjectizer. Вот сейчас готовлю сравнение SObjectizer с FIPA Abstract Architecture. Документацию по TIB/Rendezvous выкачал, но еще не прочитал. Как только прочту, смогу сделать более тчательное сравнение.

Пока (обладая знаниями о TIB/Rendezvous на уровне небольшого обзора в "Распределенных системах" Таненбаума) могу сказать, что SObjectizer -- это в первую очередь инструмент для упрощения разработки многопоточных приложений в которых отдельные сущности можно представить в виде конечных автоматов (агентов). Сообщения в SObjectizer это просто механизм для организации взаимодействия между такими сущностями. Возможности создания распределенных приложений и выхода сообщений за границы процесса стали побочным эффектом первоначальной идеи. Хотя эффектом, который сразу был оценен по достоинству.

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

Нужно так же сказать, что для упрощения построения на основе SObjectizer распределенных приложений нами была разработана библиотека Message Box API (mbapi), которая в чем-то напоминает систему согласования. Эта библиотека так же будет выпущена как OpenSource продукт, но после выхода стабильной версии SObjectizer 4.4.

Если останавливаться на деталях TIB/Rendezvous, то можно сказать следующее:

Знание структуры сообщений
В TIB/Rendezvous сообщения являются самоописывающими, поэтому при получения сообщения можно определить его структуру. В SObjectizer разработчик изначально должен знать структуру сообщения, более того ему должен быть доступен, как минимум, h-файл с C++ описанием сообщения.

Адресация по теме и публикация сообщений
В TIB/Rendezvous при отсылке сообщения отправитель назначает сообщению тему. А если кто-то хочет получать сообщения, то он должен подписаться на эту тему. В общем-то подобная механика есть и в SObjectizer, только у нас все темы сообщений заранее определены (в виде пары <имя агента, имя сообщения>). А в TIB/Rendezvous при подписке на тему можно использовать символы заместители (вроде NEWS.comp.*.books).

Архитектура сети распространения сообщений
TIB/Rendezvous содержит специальные демоны (rendezvous daemon и rendezvous router daemon), которые отвечают за груповую и сквозную рассылку сообщений, а так же позволяют масштабировать систему TIB/Rendezvous в больших глобальных сетях. В SObjectizer нет такой продвинутой системы маршрутизации, все необходимые коммуникационные каналы нужно организовывать внутри приложения. Аналогом rendezvous daemon, вероятно, можно считать связку агента-коммуникатора с транспортными агентами, т.к. именно они отвечают за широковещательную и целенаправленную отсылку сообщений. Но вот средств маштабирования на глобальные сети, аналогичные rendezvous router daemon, SObjectizer не имеет. Да и исходя из его нынешнего предназначения они ему вряд ли нужны.

При установлении SOP соединений SObjectizer-процессы не обмениваются информацией о том, какие темы их интересуют (т.е. на какие темы есть подписка в каждом из агентов). Вместо этого в процессе handshake происходит обмен фильтрами, т.е. именами глобальных агентов, чьи сообщения можно отсылать в SOP канал.

Механизм диспетчеризации событий
По поверхностному описанию у Таненбаума механизмы обработки событий у SObjectizer и у TIB/Rendezvous очень похожи. Разве что терминология разная, поэтому трудно оценить, что же именно отличается не будучи знатоком TIB/Rendezvous. Таненбаум говорит о наличии разных очередей событий и об объединении нескольких очередей в группы очередей. А так же о возможности назначения группам приоритетов. Аналогичные вещи происходят в SObjectizer, только все это дело скрыто под ковром SObjectizer Run-Time. И очереди событий формируются автоматически для каждого агента, который получает событие. И автоматически обрабатываются в соответствии с приоритетами. А уж смешиваются ли очереди различных агентов зависит от типа агента (пассивный, активный, член активной группы).

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

Отказоустойчивость
SObjectizer не предоставляет средств по обеспечению оказоустойчивости. Опять таки это диктуется его изначальной природой. Если приложению требуется отказоустойчивость, то приложение должно само ее обеспечить. Создание средств, похожих на отказоустойчивые группы процессов в TIB/Rendezvous, в SObjectizer возможно. Но, скорее всего, это будет просто дополнительная библиотека (такая же как mbapi), а не встроенная в SObjectizer функциональность.

Защита
SObjectizer не имеет встроенных средств для огранизации защищенных каналов, работы с ключевой информацией, аутентификацией клиентов, котролем прав клиента и пр. Для организации защищенных SOP каналов можно использовать SSL соединения (есть дополнительная библиотека транспортных агентов, использующих OpenSSL). Работа с сертификатами отдается на откуп пользователю. Так же можно организовывать защищенные каналы путем их тунелирования посредством stunnel или ssh.

Вот такой беглый обзор. Надеюсь, со временем удасться сделать более углубленный.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Конструктивная критика 3
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 28.05.06 09:50
Оценка:
Здравствуйте, remark, Вы писали:

R>3. Состояния и агент являются монолитом. Агент находится сразу во всех состояниях по крайне мере в том смысле, что он должен содержать все данные, которые нужны всем его состояниям. Это плохо, т.к. (1) нелогично, (2) может привидить к ошибкам (когда агент обращается к своей переменной-члену, которая логически не имеет смысл в текущем состоянии агента, но физически она существует) и (3) может быть расточительно (данные одного состояния большие, но требуются очень редко).

R>Хотелось бы видеть состояния, как отдельные объекты. Например:

Вот разказ о фреймворке, в котором что-то подобное сделано изначально: Реализация систем, управляемых событиями Использование конечных автоматов
Автор: А.Рахимбердыев, А.Ксенофонтов, Е.Адаменк
Дата: 26.05.06


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Конструктивная критика 3
От: remark Россия http://www.1024cores.net/
Дата: 31.05.06 11:19
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>3. Состояния и агент являются монолитом. Агент находится сразу во всех состояниях по крайне мере в том смысле, что он должен содержать все данные, которые нужны всем его состояниям. Это плохо, т.к. (1) нелогично, (2) может привидить к ошибкам (когда агент обращается к своей переменной-члену, которая логически не имеет смысл в текущем состоянии агента, но физически она существует) и (3) может быть расточительно (данные одного состояния большие, но требуются очень редко).

R>>Хотелось бы видеть состояния, как отдельные объекты. Например:

E>Вот разказ о фреймворке, в котором что-то подобное сделано изначально: Реализация систем, управляемых событиями Использование конечных автоматов
Автор: А.Рахимбердыев, А.Ксенофонтов, Е.Адаменк
Дата: 26.05.06


Да, это то о чём, я говорил — классическая модель... Тока там нету механизма доставки/обработки сообщений Т.е. на фреймворк, на основе которого можно строить приложение, он не тянет, в отличие от subj.
А так, конечно, очень приятно, что есть средство автогенерации кода.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: SObjectizer: I Love This Game!
От: Kais  
Дата: 03.08.06 11:35
Оценка:
Меня сильно мучает вопрос относительно скорости выполнения программ на SObjectizer.

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

Спасибо
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.08.06 13:42
Оценка:
Здравствуйте, Kais

Спасибо за интересный вопрос.

K>Меня сильно мучает вопрос относительно скорости выполнения программ на SObjectizer.


Меня в последнее время тоже
Мы применяем SObjectizer для создания server-side приложений и его производительности хватает за глаза, поскольку есть гораздо более тормознутые составляющие.

Однако, при выпуске SObjectizer в свободное плавание оказалось, что вопрос накладных расходов SObjectizer всерьез никогда не рассматривался, т.к. SObjectizer никогда не был узким местом. Стыдно признаться, но на серьезное профилирование SObjectizer никогда не было времени, нужно было либо расширять возможности SObjectizer, либо создавать дополнительные околоприкладные библиотеки на его основе. Только сейчас, после выхода второй беты версии 4.4 на эту задачу выделено время.

Пока же предварительные замеры показывают следующее: на нутбуке Intel Pentium M 1.5GHz, 512Mb SObjectizer показывает пропускную способность в ~66K сообщений в секунду (под Windows XP и Visual C++ 7.1 и Slackware Linux 10.2 и GCC 3.3.2). Я уверен, что в SObjectizer будет найдено не одно узкое место и пропускную способность удасться повысить.

Тем не менее, в SObjectizer и приложениях на его основе нужно учитывать два фактора, которые оказывают самое прямое влияние на производительность:
1) сообщения передаются в виде динамически созданых объектов. Поэтому скорость создания, обработки и уничтожения сообщений напрямую зависит от эффективности выполнения new/delete. Пока от этого никуда не деться, можно только оптимизировать производительность за счет кастомизации операторов new/delete для некоторых C++ классов (как на уровне SObjectizer (и это одна из ближайших целей в его развитии), так и на уровне приложения);
2) SObjectizer был предназначен для разработки многопоточных приложений, отдельные части которых физически нуждаются в работе на отдельных нативных нитях. Посему в SObjectizer есть ряд мест, где требуется синхронизация доступа к разделямым между потоками структурам данных (системный словарь, счетчики ссылок на экземпляры сообщений и на агентов). Эта синхронизация доступа так же имеет свои накладные расходы, хоть при проектировании SObjectizer мы и стремились свести их к минимуму (но избавиться от них невозможно).

Наблюдения показывают, что производительноть SObjectizer мало зависит от общего количества агентов в системе. Так, производительность тестов с 300K агентов не сильно отличается от тестов с 3K агентов. Более важными факторами является количество активных агентов (активных групп агентов), количество заявок в очереди одного агента и количество таймерных заявок. Был случай, когда в системе оказалось зарегистрированными 10K агентов, каждый из которых выставил периодическую таймерную заявку на 10 секунд. Оказалось, что таймерные заявки генерировались быстрее, чем агенты успевали их разгребать (но здесь влияли не только накладные расходы самого SObjectizer, но и время обработки сообщения каждым из агентов, а оно было не маленьким, т.к. во время обработки велось логирование на диск). Эксперименты показали, что критический момент наступал где-то на границе 7K агентов.

K>Хотелось бы узнать об особенностях использования данного подхода в приложениях в критичным быстродействием

K>(игр, например).

Я не сильно разбираюсь в программировании игр. И, насколько я понимаю, принципы работы шутеров в корне отличаются от, например, рилтаймовых стратегий. Я себе слабо представляю использование SObjectizer в шутере, а вот в стратегии реального времени -- вполне. Правда, я не знаю, достаточно ли для подобной стратегии скорости в 60K сообщений в секунду.

Может быть вы предложите какой-нибудь несложный имитационный тест, который мы бы попытались запрограммировать в SObjectizer и замерить его производительность? А затем бы опубликовали как результаты замеров, так и исходные тексты теста.

K>Спасибо


Вам спасибо за проявленный интерес.

Если не сложно, не могли бы вы сказать, откуда вы узнали про существование SObjectizer?

Если вы ознакомились с документацией/статьями о SObjectizer, то как вы находите их качество? Что, по вашему мнению, можно было бы улучшить?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 03.08.06 17:07
Оценка:
Здравствуйте, eao197, Вы писали:

E>Мы применяем SObjectizer для создания server-side приложений и его производительности хватает за глаза, поскольку есть гораздо более тормознутые составляющие.


Это вопрос.
Например, БД Oracle через oci может инсёртить ~100К записей в секунду (БД установлена на обычном ПК).
По сокету можно передавать ~40К сообщений в секунду в обе стороны одновременно (пробовал в обычной локалке Ethernet 100).


E>Пока же предварительные замеры показывают следующее: на нутбуке Intel Pentium M 1.5GHz, 512Mb SObjectizer показывает пропускную способность в ~66K сообщений в секунду (под Windows XP и Visual C++ 7.1 и Slackware Linux 10.2 и GCC 3.3.2). Я уверен, что в SObjectizer будет найдено не одно узкое место и пропускную способность удасться повысить.


15 мкс на одно сообщение на такой машине неплохо. Особенно, если учесть, что оптимизации ещё не было.
Вопрос: насколько увеличивается производительность при вертикальном масштабировании? Если на 3.0GHz будет ~132K, то это круто. Но возможен и такой вариант, что будет ~66K

Кажется ты говорил про создание маршрутизатора коротких сообщений на основе SObjectizer. Допустим требуемая пропускная способность 3К сообщений в секунду. Допустим на приём/обработку/отправку сообщения уходит 10 сообщений SObjectizer. Получается 30К/с. Т.е. 50% процессорного времени съедается фреймворком SObjectizer без выполнения какой-либо полезной работы. Т.е. собственно на приём/обработку/отправку сообщения остаётся 150 мкс. Не густо

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


E>Тем не менее, в SObjectizer и приложениях на его основе нужно учитывать два фактора, которые оказывают самое прямое влияние на производительность:

E>1) сообщения передаются в виде динамически созданых объектов. Поэтому скорость создания, обработки и уничтожения сообщений напрямую зависит от эффективности выполнения new/delete. Пока от этого никуда не деться, можно только оптимизировать производительность за счет кастомизации операторов new/delete для некоторых C++ классов (как на уровне SObjectizer (и это одна из ближайших целей в его развитии), так и на уровне приложения);

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


E>2) SObjectizer был предназначен для разработки многопоточных приложений, отдельные части которых физически нуждаются в работе на отдельных нативных нитях. Посему в SObjectizer есть ряд мест, где требуется синхронизация доступа к разделямым между потоками структурам данных (системный словарь, счетчики ссылок на экземпляры сообщений и на агентов). Эта синхронизация доступа так же имеет свои накладные расходы, хоть при проектировании SObjectizer мы и стремились свести их к минимуму (но избавиться от них невозможно).


Советую смотреть в сторону lock-free структур данных. Это может существенно увеличить как скорость обработки, т.к. и масштабируемость при увеличении потоков.
А какие имеются разделяемые структуры?
Если очереди, то сам бог велел lock-free. Если несколько потоков кладут в очередь с одной стороны и один(несколько) берут с другой, то это может происходить практически без задержек и коллизий.


Если удастся поднять производительность на порядок, то SObjectizer можно будет ставить в один ряд с такими библиотеками как ACE


E>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 03.08.06 20:15
Оценка:
Здравствуйте, remark, Вы писали:

R>По сокету можно передавать ~40К сообщений в секунду в обе стороны одновременно (пробовал в обычной локалке Ethernet 100).


Теперь добавь сюда сохранение каждого принятого сообщения в БД и логирование факта его приема и цифра уменьшится на порядок

Кстати, какого размера были сообщения? Передавались ли они в синхронном или асинхронном режиме?

R>Кажется ты говорил про создание маршрутизатора коротких сообщений на основе SObjectizer. Допустим требуемая пропускная способность 3К сообщений в секунду. Допустим на приём/обработку/отправку сообщения уходит 10 сообщений SObjectizer. Получается 30К/с. Т.е. 50% процессорного времени съедается фреймворком SObjectizer без выполнения какой-либо полезной работы. Т.е. собственно на приём/обработку/отправку сообщения остаётся 150 мкс. Не густо


3K сообщений в секунду через обычный компьютер с надлежащей их обработкой -- это фанастика. Ведь в сутки это составляет ~260M сообщений. А в месяц больше 7 миллиардов сообщений. Любой оператор сотовой связи мечтал бы иметь такой трафик и возможность обслуживать этот трафик на одной персоналке средней мощности.

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


Не так. Сообщение удаляет тот поток, который последним его обрабатывал. Я не имею точной статистики, но, по моему предположению, это далеко не всегда отправивший сообщение поток.

R>Если удастся поднять производительность на порядок, то SObjectizer можно будет ставить в один ряд с такими библиотеками как ACE


Быстрее ACE быть не получится, ведь SObjectizer работает поверх ACE


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 04.08.06 06:48
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>По сокету можно передавать ~40К сообщений в секунду в обе стороны одновременно (пробовал в обычной локалке Ethernet 100).


E>Теперь добавь сюда сохранение каждого принятого сообщения в БД и логирование факта его приема и цифра уменьшится на порядок

Я же написал выше, что Oracle, стоящий на ПК, запросто сохраняет по 10К сообщений в секунду.
Зачем логировать при нормальной работе? Тем более, что сохраняем в БД. Мы логируем только, если есть подозрения на ошибки.

E>Кстати, какого размера были сообщения? Передавались ли они в синхронном или асинхронном режиме?

По 100 байт в синхронном режиме (через send/recv)


R>>Кажется ты говорил про создание маршрутизатора коротких сообщений на основе SObjectizer. Допустим требуемая пропускная способность 3К сообщений в секунду. Допустим на приём/обработку/отправку сообщения уходит 10 сообщений SObjectizer. Получается 30К/с. Т.е. 50% процессорного времени съедается фреймворком SObjectizer без выполнения какой-либо полезной работы. Т.е. собственно на приём/обработку/отправку сообщения остаётся 150 мкс. Не густо


E>3K сообщений в секунду через обычный компьютер с надлежащей их обработкой -- это фанастика. Ведь в сутки это составляет ~260M сообщений. А в месяц больше 7 миллиардов сообщений. Любой оператор сотовой связи мечтал бы иметь такой трафик и возможность обслуживать этот трафик на одной персоналке средней мощности.


А некоторые не только мечтают, но и заключают контракты на это


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


E>Не так. Сообщение удаляет тот поток, который последним его обрабатывал. Я не имею точной статистики, но, по моему предположению, это далеко не всегда отправивший сообщение поток.


Но всё равно хороший аллокатор памяти не повредит



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: SObjectizer: I Love This Game!
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 04.08.06 06:52
Оценка:
Здравствуйте, eao197, Вы писали:

E>Пока же предварительные замеры показывают следующее: на нутбуке Intel Pentium M 1.5GHz, 512Mb SObjectizer показывает пропускную способность в ~66K сообщений в секунду (под Windows XP и Visual C++ 7.1 и Slackware Linux 10.2 и GCC 3.3.2).


А что именно замерялось?
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[6]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.08.06 07:42
Оценка:
Здравствуйте, remark, Вы писали:

R>>>По сокету можно передавать ~40К сообщений в секунду в обе стороны одновременно (пробовал в обычной локалке Ethernet 100).


E>>Теперь добавь сюда сохранение каждого принятого сообщения в БД и логирование факта его приема и цифра уменьшится на порядок

R>Я же написал выше, что Oracle, стоящий на ПК, запросто сохраняет по 10К сообщений в секунду.

Ранее говорилось
Автор: remark
Дата: 03.08.06
про 100K сообщений

Но все равно, при необходимости записи сообщений в базу пропускная способность снижается с 40K до 10K, т.е. в четыре раза

R>Зачем логировать при нормальной работе?


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

E>>Кстати, какого размера были сообщения? Передавались ли они в синхронном или асинхронном режиме?

R>По 100 байт в синхронном режиме (через send/recv)

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

R>Но всё равно хороший аллокатор памяти не повредит


Да. Только его еще сделать нужно и внедрить


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: SObjectizer: I Love This Game!
От: Аноним  
Дата: 04.08.06 07:46
Оценка:
Здравствуйте, eao197

E>Может быть вы предложите какой-нибудь несложный имитационный тест, который мы бы попытались запрограммировать в SObjectizer и замерить его производительность? А затем бы опубликовали как результаты замеров, так и исходные тексты теста.


Обязательно воспользуюсь данным предложением, когда досконально представлю общую картину процесса.

E>Если не сложно, не могли бы вы сказать, откуда вы узнали про существование SObjectizer?


Вот из этого интереснейшего топика.

E>Если вы ознакомились с документацией/статьями о SObjectizer, то как вы находите их качество? Что, по вашему мнению, можно было бы улучшить?


Очень понравилось соотношение: "теория / описание примеров" в вашей книге "SObjectizer-4 Book".
Вот все б так писали
Re[7]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 04.08.06 07:54
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>>>По сокету можно передавать ~40К сообщений в секунду в обе стороны одновременно (пробовал в обычной локалке Ethernet 100).


E>>>Теперь добавь сюда сохранение каждого принятого сообщения в БД и логирование факта его приема и цифра уменьшится на порядок

R>>Я же написал выше, что Oracle, стоящий на ПК, запросто сохраняет по 10К сообщений в секунду.

E>Ранее говорилось
Автор: remark
Дата: 03.08.06
про 100K сообщений


Не сообщений, а записей
Записи были во-первых короче среднестатистических сообщений, а во-вторых клались в неиндексированную таблицу.
Поэтому сообщений не 100K, а 10K.


E>Но все равно, при необходимости записи сообщений в базу пропускная способность снижается с 40K до 10K, т.е. в четыре раза


Про требования пропускать через маршрутизатор 10K в секунду никто не говорил. Я имею в виду, что не БД, ни сокет вполне может не быть узким местом при требованиях в 3К. Ещё время и на обработку останется.


E>>>Кстати, какого размера были сообщения? Передавались ли они в синхронном или асинхронном режиме?

R>>По 100 байт в синхронном режиме (через send/recv)

E>Т.е. использовался датаграмный режим?


Нет, tcp. Но асинхронный ввод/вывод не использовался.


R>>Но всё равно хороший аллокатор памяти не повредит


E>Да. Только его еще сделать нужно и внедрить


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



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.08.06 08:40
Оценка:
Здравствуйте, remark, Вы писали:

E>>Ранее говорилось
Автор: remark
Дата: 03.08.06
про 100K сообщений


R>Не сообщений, а записей

R>Записи были во-первых короче среднестатистических сообщений, а во-вторых клались в неиндексированную таблицу.

И еще, наверное, в рамках bulk-операции, без фиксации транзакции после каждого инсерта.

E>>Но все равно, при необходимости записи сообщений в базу пропускная способность снижается с 40K до 10K, т.е. в четыре раза


R>Про требования пропускать через маршрутизатор 10K в секунду никто не говорил. Я имею в виду, что не БД, ни сокет вполне может не быть узким местом при требованиях в 3К. Ещё время и на обработку останется.


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

Но вообще это уже офтопик. Предлагаю завязать.

E>>Т.е. использовался датаграмный режим?


R>Нет, tcp. Но асинхронный ввод/вывод не использовался.


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 04.08.06 08:44
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


E>>>Ранее говорилось
Автор: remark
Дата: 03.08.06
про 100K сообщений


R>>Не сообщений, а записей

R>>Записи были во-первых короче среднестатистических сообщений, а во-вторых клались в неиндексированную таблицу.

E>И еще, наверное, в рамках bulk-операции,


Ессно

E>без фиксации транзакции после каждого инсерта.


С фиксацией



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.08.06 08:48
Оценка:
Здравствуйте, Аноним, Вы писали:

E>>Может быть вы предложите какой-нибудь несложный имитационный тест, который мы бы попытались запрограммировать в SObjectizer и замерить его производительность? А затем бы опубликовали как результаты замеров, так и исходные тексты теста.


А>Обязательно воспользуюсь данным предложением, когда досконально представлю общую картину процесса.


Ok. Если вы сможете сформулировать подобный тест то это будет хорошим подспорьем в развитии SObjectizer.

E>>Если вы ознакомились с документацией/статьями о SObjectizer, то как вы находите их качество? Что, по вашему мнению, можно было бы улучшить?


А>Очень понравилось соотношение: "теория / описание примеров" в вашей книге "SObjectizer-4 Book".

А>Вот все б так писали

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.08.06 09:09
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

E>>Пока же предварительные замеры показывают следующее: на нутбуке Intel Pentium M 1.5GHz, 512Mb SObjectizer показывает пропускную способность в ~66K сообщений в секунду (под Windows XP и Visual C++ 7.1 и Slackware Linux 10.2 и GCC 3.3.2).


ANS>А что именно замерялось?


Было два основных теста. В первом создавалось N агентов и определялось M из них, которым нужно отослать сообщения. Начинался отсчет времени и первому из этих M агентов осылалось пустое сообщение. Он получал его и отсылал следующему из этого списка, тот следующему и т.д. до тех пор, пока все M агентов не отработают. Тут и фиксируется время окончания теста. Все агенты пассивные, работают на контексте одной нити. Значение N и M задаются в командной строке. Так, величина в 66K получилась при N=300000 и M=20000.

Второй тест создавал десять активных агентов -- пять sender-ов и пять receiver-ов. Каждый sender при своем старте отсылал 10K сообщений своему receiver-у. После того, как sender завершал свою работу он информировал об этом специального агента shutdowner-а. После того, как receiver получал все 10K сообщений и завершал свою работу он информировал об этом того же shutdowner-а. После того, как shutdowner получал сообщения о завершении от всех 10 агентов он останавливал SObjectizer. Фиксировалось время между стартом и остановом SObjectizer. Текст этого теста в следующем сообщении.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game! (код теста)
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.08.06 09:12
Оценка:
E>Второй тест создавал десять активных агентов -- пять sender-ов и пять receiver-ов. Каждый sender при своем старте отсылал 10K сообщений своему receiver-у. После того, как sender завершал свою работу он информировал об этом специального агента shutdowner-а. После того, как receiver получал все 10K сообщений и завершал свою работу он информировал об этом того же shutdowner-а. После того, как shutdowner получал сообщения о завершении от всех 10 агентов он останавливал SObjectizer. Фиксировалось время между стартом и остановом SObjectizer. Текст этого теста в следующем сообщении.

Вот код этого теста:
/*
    Тестирование режима блокирования ядра SObjectizer в
    функции send_msg.

    Пять активных агентов будут генерировать по 10000 сообщений,
    которые будут обрабатывать пять других активных агентов.
    Время работы теста при read-only блокировках должно
    отличаться от времени работы при read-write блокировках.
*/

#include <iostream>

#include <stdio.h>
#include <time.h>

#include <ace/OS_main.h>

#include <so_4/api/h/api.hpp>
#include <so_4/rt/h/rt.hpp>

#include <so_4/timer_thread/simple/h/pub.hpp>
#include <so_4/disp/active_obj/h/pub.hpp>

const int messages = 10000;

// Класс агента, который завершит работу теста.
class    a_shutdowner_t
    :    public so_4::rt::agent_t
{
    typedef so_4::rt::agent_t base_type_t;
    private :
        // Количество полученных msg_shutdown.
        unsigned int    m_shutdown_received;
        // Количество ожидаемых msg_shutdown.
        unsigned int    m_shutdown_awaiting;

    public :
        a_shutdowner_t(
            unsigned int shutdown_awaiting )
        :    base_type_t( "a_shutdowner" )
        ,    m_shutdown_received( 0 )
        ,    m_shutdown_awaiting( shutdown_awaiting )
        {}
        virtual ~a_shutdowner_t()
        {}

        struct    msg_shutdown {};

        virtual const char *
        so_query_type() const;

        virtual void
        so_on_subscription()
        {
            so_subscribe( "evt_shutdown", "msg_shutdown" );
        }

        void
        evt_shutdown(
            const so_4::rt::event_data_t & )
        {
            if( ++m_shutdown_received >= m_shutdown_awaiting )
                so_4::api::send_msg(
                    so_4::rt::sobjectizer_agent_name(),
                    "msg_normal_shutdown", 0 );
        }
};

SOL4_CLASS_START( a_shutdowner_t )

    SOL4_MSG_START( msg_shutdown, a_shutdowner_t::msg_shutdown )
    SOL4_MSG_FINISH()

    SOL4_EVENT( evt_shutdown )

    SOL4_STATE_START( st_normal )
        SOL4_STATE_EVENT( evt_shutdown )
    SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

// Класс тестового агента, который отсылает сообщения.
class    a_sender_t
    :    public so_4::rt::agent_t
{
    typedef so_4::rt::agent_t base_type_t;
    private :
        // Имя получателя сообщения.
        std::string    m_receiver_name;
    public :
        a_sender_t(
            const std::string & self_name,
            const std::string & receiver_name )
        :    base_type_t( self_name )
        ,    m_receiver_name( receiver_name )
        {
            so_add_traits(
                so_4::disp::active_obj::query_active_obj_traits() );
        }
        virtual ~a_sender_t()
        {}

        virtual const char *
        so_query_type() const;

        virtual void
        so_on_subscription()
        {
            so_subscribe( "evt_start",
                so_4::rt::sobjectizer_agent_name(), "msg_start" );
        }

        void
        evt_start(
            const so_4::rt::event_data_t & )
        {
            for( unsigned int i = 0; i != messages; ++i )
                so_4::api::send_msg( m_receiver_name,
                    "msg_my", 0 );
            so_4::api::send_msg( "a_shutdowner",
                "msg_shutdown", 0 );
        }
};

SOL4_CLASS_START( a_sender_t )

    SOL4_EVENT( evt_start )

    SOL4_STATE_START( st_normal )
        SOL4_STATE_EVENT( evt_start )
    SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

// Класс тестового агента, который получает сообщения.
class    a_receiver_t
    :    public so_4::rt::agent_t
{
    typedef so_4::rt::agent_t base_type_t;
    public :
        a_receiver_t(
            const std::string & self_name )
        :    base_type_t( self_name )
        ,    m_received( 0 )
        {
            so_add_traits(
                so_4::disp::active_obj::query_active_obj_traits() );
        }
        virtual ~a_receiver_t()
        {
        }

        struct    msg_my {};

        virtual const char *
        so_query_type() const;

        virtual void
        so_on_subscription()
        {
            so_subscribe( "evt_my", "msg_my" );
        }

        void
        evt_my()
        {
            ++m_received;
            if( messages == m_received )
                so_4::api::send_msg( "a_shutdowner",
                    "msg_shutdown", 0 );
        }

    private :
        // Количество полученных сообщений.
        int    m_received;
};

SOL4_CLASS_START( a_receiver_t )

    SOL4_MSG_START( msg_my, a_receiver_t::msg_my )
    SOL4_MSG_FINISH()

    SOL4_EVENT( evt_my )

    SOL4_STATE_START( st_normal )
        SOL4_STATE_EVENT( evt_my )
    SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()

int
main( int, char ** )
{
    // Создаем кооперацию из 6 тестовых агентов.
    a_sender_t * a_sender_1 = new a_sender_t(
        "a_sender_1", "a_receiever_1" );
    a_sender_t * a_sender_2 = new a_sender_t(
        "a_sender_2", "a_receiever_2" );
    a_sender_t * a_sender_3 = new a_sender_t(
        "a_sender_3", "a_receiever_3" );
    a_sender_t * a_sender_4 = new a_sender_t(
        "a_sender_4", "a_receiever_4" );
    a_sender_t * a_sender_5 = new a_sender_t(
        "a_sender_5", "a_receiever_5" );
    a_receiver_t * a_receiver_1 = new a_receiver_t(
        "a_receiever_1" );
    a_receiver_t * a_receiver_2 = new a_receiver_t(
        "a_receiever_2" );
    a_receiver_t * a_receiver_3 = new a_receiver_t(
        "a_receiever_3" );
    a_receiver_t * a_receiver_4 = new a_receiver_t(
        "a_receiever_4" );
    a_receiver_t * a_receiver_5 = new a_receiver_t(
        "a_receiever_5" );
    a_shutdowner_t * a_shutdowner = new a_shutdowner_t( 10 );

    so_4::rt::agent_t * agents[] =
    {
        a_sender_1, a_sender_2, a_sender_3, a_sender_4, a_sender_5,
        a_receiver_1, a_receiver_2, a_receiver_3,
            a_receiver_4, a_receiver_5,
        a_shutdowner
    };
    so_4::rt::dyn_agent_coop_t * coop = new so_4::rt::dyn_agent_coop_t(
        "sample", agents, sizeof( agents ) / sizeof( agents[ 0 ] ) );

    clock_t finish, start = clock();
    so_4::ret_code_t rc = so_4::api::start(
        // Диспетчер будет уничтожен при выходе из start().
        so_4::disp::active_obj::create_disp(
            // Таймер будет уничтожен диспетчером.
            so_4::timer_thread::simple::create_timer_thread(),
            so_4::auto_destroy_timer ),
        so_4::auto_destroy_disp,
        coop );
    finish = clock();
    if( rc )
    {
        std::cerr << "start: " << rc << std::endl;
    }
    else
        std::cerr << "successful finish: "
            << double( finish - start ) / CLOCKS_PER_SEC
            << std::endl;

    return int( rc );
}


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game!
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 04.08.06 09:57
Оценка:
Здравствуйте, eao197, Вы писали:

E>>>Пока же предварительные замеры показывают следующее: на нутбуке Intel Pentium M 1.5GHz, 512Mb SObjectizer показывает пропускную способность в ~66K сообщений в секунду (под Windows XP и Visual C++ 7.1 и Slackware Linux 10.2 и GCC 3.3.2).


ANS>>А что именно замерялось?


E>Было два основных теста. В первом создавалось N агентов и определялось M из них, которым нужно отослать сообщения. Начинался отсчет времени и первому из этих M агентов осылалось пустое сообщение. Он получал его и отсылал следующему из этого списка, тот следующему и т.д. до тех пор, пока все M агентов не отработают. Тут и фиксируется время окончания теста. Все агенты пассивные, работают на контексте одной нити. Значение N и M задаются в командной строке. Так, величина в 66K получилась при N=300000 и M=20000.


Не совсем понял. 66К сообщений прошедших весь "круг" или от одного агента к другому?
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[6]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 04.08.06 10:15
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

E>>Было два основных теста. В первом создавалось N агентов и определялось M из них, которым нужно отослать сообщения. Начинался отсчет времени и первому из этих M агентов осылалось пустое сообщение. Он получал его и отсылал следующему из этого списка, тот следующему и т.д. до тех пор, пока все M агентов не отработают. Тут и фиксируется время окончания теста. Все агенты пассивные, работают на контексте одной нити. Значение N и M задаются в командной строке. Так, величина в 66K получилась при N=300000 и M=20000.


ANS>Не совсем понял. 66К сообщений прошедших весь "круг" или от одного агента к другому?


Тест показывает за какое время происходит последовательная отсылка/обработка M сообщений, если в системе зарегистрировано N агентов. У меня 20000 сообщений отсылаются за ~0.3 секунды, что дает где-то около 66K в секунду (66K отсылаются за ~0.97sec). Причем этот показатель оказывается стабильным при изменении N и M в разных направлениях.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: SObjectizer: I Love This Game!
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 15.08.06 13:55
Оценка: 28 (1)
Здравствуйте, eao197, Вы писали:

ЗЫ У тебя в подписи битая ссылка: http://sobjectizer.sourceforge.org/ не открывается. Нужно http://sobjectizer.sourceforge.net/
http://www.smalltalk.ru | << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 15.08.06 14:02
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>ЗЫ У тебя в подписи битая ссылка: http://sobjectizer.sourceforge.org/ не открывается. Нужно http://sobjectizer.sourceforge.net/


Млин! А ведь казалось, что проверял...
Спасибо!


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: Аноним  
Дата: 21.08.06 18:48
Оценка:
Возможно не все понял из статьи, но разве это не повторяет идеи библиотеки Qt, и механизмов signal->slot?
Сорри, не хватило терпения прочитать все обсуждение, может уже и есть упоминание об этом.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.08.06 21:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Возможно не все понял из статьи, но разве это не повторяет идеи библиотеки Qt, и механизмов signal->slot?

А>Сорри, не хватило терпения прочитать все обсуждение, может уже и есть упоминание об этом.

Спасибо за интересный вопрос, такого сравнения здесь еще не было.

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

А различия таковы:
* синхронность signal-slot и асинхронность событий в SObjectizer. В Qt (по крайней мере в Qt3, с которой мне доводилось работать) все слоты гарантированно отрабатывали до возврата из emit-а. Для того, чтобы передать Qt-событие в другую нить на обработку требовалось создавать объект QEvent и помещать его в очередь нужной нити через postEvent (таким образом работает SObjectizer-овский диспетчер для главной нити Qt3). В SObjectizer возврат из send_msg может произойти как до обработки подписанных на сообщение событий, во время обработки или после обработки. События (т.е. экземпляры событий) автоматически размещаются в очередях нужных нитей и там обрабатываются;

* в схеме signal-slot нельзя управлять приоритетами слотов;

* в схеме signal-slot слоты никак не связаны с состоянием объекта. Если в каком-то состоянии объект не хочет, чтобы его слот вызывался, то объект сам должен делать disconnect с последующим connect-ом. В SObjectizer события явно распределены по состояниям, и если событие запрещено к обработке в текущем состоянии, то событие просто игнорируется;

* в Qt все сигналы и слоты привязаны к конкретной сигнатуре сигнала/слота. В SObjectizer эта связь менее сильная. Во-первых, в SObjectizer событие может иметь в качестве инцидентов сообщения, чей тип для события вообще не известен (экземпляр сообщения передается в событие как void *). Во-вторых, событие в SObjectizer может получить только один указатель/ссылку на объект. В Qt сигнатура сигнала/слота может содержать произвольное количество аргументов разных типов.

Ну и еще одно принципиальное различие (хотя оно больше техническое, нежели идеологическое). В Qt вспомогательный код генерируется moc компилятором почти по обычным C++ описаниям класса Qt-объекта. В SObjectizer для этого приходится вручную (пока) описывать класс агента для SObjectizer в виде специального кода на макросах (чем-то напоминающего макросные коды MFC и wxWidgets).


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: OSE
От: remark Россия http://www.1024cores.net/
Дата: 04.01.07 22:22
Оценка: 32 (1)
Здравствуйте, Евгений Охотников, Вы писали:

Наткнулся тут на такую библиотеку OSE
Судя по инфе, библиотека зародилась в 1990 и 2006 ещё выходят новые релизы.

Собственно к чему я — там есть Event Driven Systems. Может тебе будет интересно поглядеть и сравнить.
У тебя, я так понимаю, это больше фреймворк для приложений, а там больше с уклоном системного компонета.
Вот самый простенький пример оттуда:

class Agent1 : public OTC_EVAgent
 {
   public:
     Agent1() : count(0) {}
     void handle(OTC_Event* e);
   private:
     u_int count;
 };
 
 void Agent1::handle(OTC_Event* e)
 {
   if (e->type() == OTCEV_Action::typeId())
   {
     count++;
     cout << count << endl;
     if (count < 10)
     {
       e->queue(id());
       return;
     }
   }
   e->destroy();
 }
 
 main()
 {
   Agent1 a;
   OTC_Dispatcher::initialise();
   OTCEV_Action* e = new OTCEV_Action(0);
   e->queue(a.id());
   OTC_Dispatcher::run();
   return 0;
 }


Диспатчинг сообщений надо делать вручную.
Зато там есть signals, alarms, timers and i/o events в качестве источников событий. Этим перекликается с ACE_Reactor.
Т.е. нечно среднее между Агентом и клиентом Реактора...



з.ы. там ещё есть некий makeit. Может будет как-то интересно в свете mxx_ru. Там типа скриптов простеньких.




1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: OSE
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 05.01.07 11:04
Оценка:
Здравствуйте, remark, Вы писали:

R>Наткнулся тут на такую библиотеку OSE


Спасибо за ссылочку.

<...>

R>Т.е. нечно среднее между Агентом и клиентом Реактора...


Мне больше показалось, что это среднее между ACE и Qt
Тем более, что солидный возраст наложил свой отпечаток на их API.

А вообще,
* как-то по счетчику загрузок не кажется, что она очень востребованна,
* Qt-ная лицензия, т.е. для закрытых проектов за нее еще и деньги платить нужно

R>з.ы. там ещё есть некий makeit. Может будет как-то интересно в свете mxx_ru. Там типа скриптов простеньких.


Ужас Очередная надстройка над GNU make в make-ровском же синтаксисе


R>



SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: OSE
От: remark Россия http://www.1024cores.net/
Дата: 05.01.07 14:41
Оценка:
Здравствуйте, eao197, Вы писали:

E>Мне больше показалось, что это среднее между ACE и Qt

E>Тем более, что солидный возраст наложил свой отпечаток на их API.

Да, это у многих библиотек такая болезнь. Или возраст или чрезмерная портируемость плохо сказываются...

E>А вообще,

E>* как-то по счетчику загрузок не кажется, что она очень востребованна,
E>* Qt-ная лицензия, т.е. для закрытых проектов за нее еще и деньги платить нужно

Ну загрузить-то можно, а лицензия на идеи не распространяется
Мне так кажется, что идеи — это самое главное, а код набить это не так долго. Сколько бы у тебя ушло сейчас "набить" SObjectizer ещё раз, если ты сейчас этим занялся? Я думаю, не очень много, да ещё бы он и лучше получился


R>>

E>

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: OSE
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 05.01.07 16:18
Оценка:
Здравствуйте, remark, Вы писали:

E>>* Qt-ная лицензия, т.е. для закрытых проектов за нее еще и деньги платить нужно


R>Ну загрузить-то можно, а лицензия на идеи не распространяется


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

R>Мне так кажется, что идеи — это самое главное, а код набить это не так долго. Сколько бы у тебя ушло сейчас "набить" SObjectizer ещё раз, если ты сейчас этим занялся? Я думаю, не очень много, да ещё бы он и лучше получился


Не факт на самом деле. Если не ошибаюсь, ядро нынешнего SObjectizer было сделано в самом начале, уже почти пять лет назад всего за месяц. Тогда просто был очень удачный период, когда все идеи уже были созревшими, код лился рекой и, что не маловажно, были понятны требования со стороны проектов, в которые планировалось его внедрить. Сейчас страшно подумать, но тогда за месяц было написано и оттестировано порядка 15-20т. строк кода.

Давно я уже не повторял таких трудовых подвигов

R>


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 28.04.07 08:08
Оценка:
Здравствуйте, Евгений Охотников, Вы писали:

А нету ли случаем для SObjectizer какого-то краткого списка поддерживаемых фич и компонентов, типа документации Doxуgen по классам. Вроде на eao197.narod.ru и sourceforge не видно. Типа как здесь.
Чего хотелось бы — хотелось бы, что бы можно было это быстро просмотреть и оценить , что есть и как оно есть, а чего нет.
Ну вот, например, по ссылке в ACE можно сразу посмотреть — "так, ACE_RW_Mutex там есть, функции TryLock() предоставляет" и т.д.
А то вот я как-то упускал из виду, что в SObjectizer есть tcp каналы с автоматическим реконнектом... может ещё что интересное упустил... хотелось бы как-то так всё это быстро окинуть взглядом, но в то же время, что бы можно было при желании заострить внимание на каких-то делалях, типа того, что в конструктор tcp канала можно передать период реконнекта и функциональность реконнекта будет автоматически включена...


Ещё такой вопрос. То, что синхронного взаимодействия "нет и нет будет", я понял... ну в принципе наверное и правильно...
А тем не менее нету ли какой-то другой поддержки паттерна запрос-ответ в фреймворке?
Понятно, что можно вручную отослать некий request_id, получатель вставит его в ответ, а потом проверять его и т.д. Но нету ли каких-то шорт-катов для поддержки такого взаимодействия?
Например, есть агент агент_читающий_настройки_из_конфигурационного_файла. К нему обращаются множество других клиентов с запросом считать такой-то параметр. А он потом отвечает другим сообщением, в котором идёт само значение параметра.
Хотелось бы, что бы как-то автоматически сматчился запрос и ответ и ответ попал только тому агенту, который отправил запрос, а не ко всем. Если ещё агенты сидят в разных потоках, то будет thundering herd problem.
Или такая задача решается как-то по другому в SObjectizer?


Ещё заодно по поводу состояний объектов. А действительно часто необходимы состояния в реальных задачах? Ты не мог бы привести какие-то более-менее реальные примеры агентов, которым действительно полезны состояния. Ну кроме коммуникационного канала, у которого есть state_connected, state_disconnected и т.д.
А то я вот думаю, может быть поддержку состояний более целессобразно отдавать самому агенту... Ну я агентов пока много не делал, поэтому самому не получается оценить...


А можно ли в рамках SObjectizer реализовать т.н. фильтры?
Под фильтрами я имею в виду следующее. Допустим есть некий агент агент_достающий_значения_из_бд. Агент отлаженный и имеющийся в качестве готового компонета. Допустим он обрабатывает сообщения do_read_value, а после считывания данных из бд отвечает сообщением on_read_value. И допустим есть уже агента-клиенты, которые пользуются этим агентом.
Я хочу добавить в систему агент_который_кэширует_значения_из_бд, причём прозрачно и для агента-сервера и для агентов-клиентов. Т.е. агент_который_кэширует_значения_из_бд регистрируется как фильтр на сообщения do_read_value, если требуемое значение есть в его кэше, то он сразу отвечает on_read_value и отменяет дальнейшую обработку сообщения, если значения в кэше нет, то он передаёт управление "дальше". Когда же идёт ответное on_read_value, то агент_который_кэширует_значения_из_бд должен его тоже перехватить и закэшировать и передать "дальше".
Имхо для систем именно компонентных и именно компонуемых из готовых компонетов, а я так понимаю, что это одно из серьёзных приемуществ агентных систем, такая функциональность была бы очень полезной...


И ещё последний момент. Раз ты этим занимался, наверное у тебя ссылочки на другие подобные агентные фреймворки... ты не мог бы что-нибудь подкинуть...
Ну вот типа как я кидал на OSE Event Driven Systems
Интересуют ссылки именно на реальные, так сказать промышленные фреймворки/библиотеки, а не теоретические ресёрчи. В принципе на любых языках, приемущественно, конечно, C++, но пойдёт и C#/Java.


Заранее благодарен...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 28.04.07 10:25
Оценка: 16 (1)
Здравствуйте, remark, Вы писали:

R>А нету ли случаем для SObjectizer какого-то краткого списка поддерживаемых фич и компонентов, типа документации Doxуgen по классам. Вроде на eao197.narod.ru и sourceforge не видно. Типа как здесь.

R>Чего хотелось бы — хотелось бы, что бы можно было это быстро просмотреть и оценить , что есть и как оно есть, а чего нет.
R>Ну вот, например, по ссылке в ACE можно сразу посмотреть — "так, ACE_RW_Mutex там есть, функции TryLock() предоставляет" и т.д.

Doxygen документация по SObjectizer есть: вот, например -- оно?
Есть там, конечно, недочеты, ведь мы написали основной объем кода в SObjectizer был написан еще до того, как начали использовать Doxygen.

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

R>А тем не менее нету ли какой-то другой поддержки паттерна запрос-ответ в фреймворке?
R>Понятно, что можно вручную отослать некий request_id, получатель вставит его в ответ, а потом проверять его и т.д. Но нету ли каких-то шорт-катов для поддержки такого взаимодействия?
R>Например, есть агент агент_читающий_настройки_из_конфигурационного_файла. К нему обращаются множество других клиентов с запросом считать такой-то параметр. А он потом отвечает другим сообщением, в котором идёт само значение параметра.
R>Хотелось бы, что бы как-то автоматически сматчился запрос и ответ и ответ попал только тому агенту, который отправил запрос, а не ко всем. Если ещё агенты сидят в разных потоках, то будет thundering herd problem.
R>Или такая задача решается как-то по другому в SObjectizer?

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

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

R>Ещё заодно по поводу состояний объектов. А действительно часто необходимы состояния в реальных задачах? Ты не мог бы привести какие-то более-менее реальные примеры агентов, которым действительно полезны состояния. Ну кроме коммуникационного канала, у которого есть state_connected, state_disconnected и т.д.

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

Я сейчас сделал поиск по одному из самых больших своих проектов на SObjectizer-е. Оказалось, что самое большое количество состояний как раз у агентов, которые либо обрабатывают входящие/исходящие соединения (те самые st_connecting, st_connected, st_disconnected), либо сами являются некоторым оконечными точками. У остальных агентов либо одно состояние (st_normal), в котором выполняется вся работа, либо два-три состояния (st_initial, в котором агент начинает сам себя раскручивать, st_configured -- когда агент полностью готов к работе, st_not_configured -- когда работа невозможна из-за ошибок конфигурирования).

Но могу привести пару примеров с состояниями:

1) стабилизатор исходящего трафика -- агент, задача которого выдавать исходящие пакеты в заданном темпе. Хотя сами пакеты могут приходить к нему в произвольном темпе. У данного агента всего два состояния: st_free, когда он свободен и может отправить исходящий пакет дальше. И st_timeout, когда нужно выждать паузу перед отсылкой следующего пакета. Упрощенный принип таков -- когда агент в состоянии st_free, то исходящий пакет сразу идет наружу, а агент переходит в состояние st_timeout и оправляет сам себе сообщение msg_timeout. Пока агент находится в st_timeout все исходяшие пакеты блокируются. Когда в st_timeout он получает msg_timeout, он возвращается в состояние st_free.

2) агент, который контролирует работу внешнего процесса с автоматическим перезапуском в случае падения внешнего процесса. Там есть состояния (если не ошибаюсь): st_launching (в это время внешнему процессу дается шанс на успешный стар), st_started (внешний процесс успешно запущен и работает), st_stopping (в это время внешнему процессу дается шанс корректно завершить свою работу), st_stopped (внешний процесс не работает).

Такие простые наборы состояний, тем не менее, позволяют лучше представить себе работу агента по его декларативному описанию. Еще одна важная вещь -- обработчики входа/выхода в/из состояния выполняют важный объем работы. Например, когда агент входит в состояние st_launcing, он:
— стартует процесс,
— оправляет самому себе отложенное сообщение, по пришествии которого будет проверено, работает ли запущенный процесс или нет.

Чем-то состояния и обработчики входа/выхода позволяют реализовывать агентов довольно близко к тому, как логика работы агентов могла бы быть представлена на UML диаграмме состояний.

Еще одна полезная фича состояний, которая проявляется при использовании специального фреймворка для мониторинга SObjectizer-а: состояния агента можно видеть из-вне приложения. И на основании имени состояния строить предположение о том, что происходит с приложением. Вот, например, st_bound_trx -- это имена состояний агентов:

Этот фреймворк так же со временем будет опубликован на SourceForge.

R>А можно ли в рамках SObjectizer реализовать т.н. фильтры?

R>Под фильтрами я имею в виду следующее. Допустим есть некий агент агент_достающий_значения_из_бд. Агент отлаженный и имеющийся в качестве готового компонета. Допустим он обрабатывает сообщения do_read_value, а после считывания данных из бд отвечает сообщением on_read_value. И допустим есть уже агента-клиенты, которые пользуются этим агентом.
R>Я хочу добавить в систему агент_который_кэширует_значения_из_бд, причём прозрачно и для агента-сервера и для агентов-клиентов. Т.е. агент_который_кэширует_значения_из_бд регистрируется как фильтр на сообщения do_read_value, если требуемое значение есть в его кэше, то он сразу отвечает on_read_value и отменяет дальнейшую обработку сообщения, если значения в кэше нет, то он передаёт управление "дальше". Когда же идёт ответное on_read_value, то агент_который_кэширует_значения_из_бд должен его тоже перехватить и закэшировать и передать "дальше".
R>Имхо для систем именно компонентных и именно компонуемых из готовых компонетов, а я так понимаю, что это одно из серьёзных приемуществ агентных систем, такая функциональность была бы очень полезной...

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

Возможность перехвата сообщений у нас сделана на основе отдельной библиотеки mbapi (message box api), которая построена поверх SObjectizer. Как раз там то, что ты описал и используется на полную катушку. И это действительно очень удобно и востребованно. Библиотека mbapi так же будет опубликована на SourceForge.


Подозреваю, что возник вопрос -- когда же все это будет опубликовано
Ответить на него не просто. Я бы очень хотел, чтобы финальная версия SObjectizer 4.4 вышла в этом году (ближе к концу). А до этого запланировано, как минимум, еще две бета-версии. Часть библиотек, которые мы создали поверх SObjectizer, хотелось бы серьезно переработать -- многие из них создавались достаточно давно и, поэтому, содержат много чего устаревшего. Особенно это касается мониторинга и mbapi. Но, надеюсь, к концу года и они будут опубликованы.

R>И ещё последний момент. Раз ты этим занимался, наверное у тебя ссылочки на другие подобные агентные фреймворки... ты не мог бы что-нибудь подкинуть...

R>Ну вот типа как я кидал на OSE Event Driven Systems
R>Интересуют ссылки именно на реальные, так сказать промышленные фреймворки/библиотеки, а не теоретические ресёрчи. В принципе на любых языках, приемущественно, конечно, C++, но пойдёт и C#/Java.

Что касается именно агентных фреймворков, то я о таких не слышал (опять же, чукча не читатель, чукча писатель ). Об агентных системах упоминалось в книге Распределенные системы. Принципы и парадигмы
Автор: Евгений Охотников
Дата: 22.05.06
. Но, насколько я знаю, все это за рамки ресерчей в промышленное использование не попало.

Ближе всего к SObjectizer, как мне кажется, системы обмена сообщениями. Например, TIBCO Randevouz. Или OpenSource библиотека Spread Toolkit.

Из не мейнстримовых пока вещей конкурентами SObjectizer я бы назвал язык Erlang и библиотеку Actors в языке Scala.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 30.04.07 15:20
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>А нету ли случаем для SObjectizer какого-то краткого списка поддерживаемых фич и компонентов, типа документации Doxуgen по классам


E>Doxygen документация по SObjectizer есть: вот, например -- оно?


Оно. Спасибо.


E>Нет, пока готовых рецептов для таких вещей нет. Но, я буду признателен, если подобные предложения будут поступать и, скажем фиксироваться в feature requests на SourceForge.


А там по-русски можно?
Ну вообще это будет не совсем честный реквест, т.к. я собственно пользователем sobjectizer не являюсь...

E>По поводу отсылки сообщения-ответа конкретному получателю могу навскидку предложить такой вариант:

E>* в сообщении-запросе передавать отдельным полем имя агента-инициатора запроса;
E>* ответное сообщение будет отсылаться целенаправлено тому агенту, имя которого было в запросе.

Понятно.

Я имею в виду что-то типа такого:

void on_msg(msg& req)
{
  //...
  msg2 ack (...);
  answer_for(req, ack);
}


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



E>Я сейчас сделал поиск по одному из самых больших своих проектов на SObjectizer-е. Оказалось, что самое большое количество состояний как раз у агентов, которые либо обрабатывают входящие/исходящие соединения (те самые st_connecting, st_connected, st_disconnected), либо сами являются некоторым оконечными точками. У остальных агентов либо одно состояние (st_normal), в котором выполняется вся работа, либо два-три состояния (st_initial, в котором агент начинает сам себя раскручивать, st_configured -- когда агент полностью готов к работе, st_not_configured -- когда работа невозможна из-за ошибок конфигурирования).


E>Но могу привести пару примеров с состояниями:


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


E>Чем-то состояния и обработчики входа/выхода позволяют реализовывать агентов довольно близко к тому, как логика работы агентов могла бы быть представлена на UML диаграмме состояний.


А вот это интересно, об этом я не подумал...


E>Еще одна полезная фича состояний, которая проявляется при использовании специального фреймворка для мониторинга SObjectizer-а: состояния агента можно видеть из-вне приложения. И на основании имени состояния строить предположение о том, что происходит с приложением. Вот, например, st_bound_trx -- это имена состояний агентов:

E>
E>Этот фреймворк так же со временем будет опубликован на SourceForge.

Круто! Именно таких вещей обычно не хватает библиотекам.


R>>А можно ли в рамках SObjectizer реализовать т.н. фильтры?

R>>Под фильтрами я имею в виду следующее. Допустим есть некий агент агент_достающий_значения_из_бд. Агент отлаженный и имеющийся в качестве готового компонета. Допустим он обрабатывает сообщения do_read_value, а после считывания данных из бд отвечает сообщением on_read_value. И допустим есть уже агента-клиенты, которые пользуются этим агентом.
R>>Я хочу добавить в систему агент_который_кэширует_значения_из_бд, причём прозрачно и для агента-сервера и для агентов-клиентов. Т.е. агент_который_кэширует_значения_из_бд регистрируется как фильтр на сообщения do_read_value, если требуемое значение есть в его кэше, то он сразу отвечает on_read_value и отменяет дальнейшую обработку сообщения, если значения в кэше нет, то он передаёт управление "дальше". Когда же идёт ответное on_read_value, то агент_который_кэширует_значения_из_бд должен его тоже перехватить и закэшировать и передать "дальше".
R>>Имхо для систем именно компонентных и именно компонуемых из готовых компонетов, а я так понимаю, что это одно из серьёзных приемуществ агентных систем, такая функциональность была бы очень полезной...

E>В чистом SObjectizer-е такой возможности нет. У меня были кое-какие мысли по поводу организации перехвата сообщений. Но удачного решения я не нашел


А в чём была проблема? В том как это реализовать с т.з. пользователя или как это реализовать внутри или прикрутить к существующему фреймворку?

E>Возможность перехвата сообщений у нас сделана на основе отдельной библиотеки mbapi (message box api), которая построена поверх SObjectizer. Как раз там то, что ты описал и используется на полную катушку. И это действительно очень удобно и востребованно. Библиотека mbapi так же будет опубликована на SourceForge.


А на сколько она интегрируется с самим SObjectizer?
Т.е. как бы это сказать, насколько агенты mbapi являются агентами SObjectizer и наоборот. Т.е. mbapi — это полная обёртка над SObjectizer, как MFC над WinAPI или приложение пишется на SObjectizer и mbapi охватывает только некоторые части...


E>Подозреваю, что возник вопрос -- когда же все это будет опубликовано

E>Ответить на него не просто. Я бы очень хотел, чтобы финальная версия SObjectizer 4.4 вышла в этом году (ближе к концу). А до этого запланировано, как минимум, еще две бета-версии. Часть библиотек, которые мы создали поверх SObjectizer, хотелось бы серьезно переработать -- многие из них создавались достаточно давно и, поэтому, содержат много чего устаревшего. Особенно это касается мониторинга и mbapi. Но, надеюсь, к концу года и они будут опубликованы.



E>Ближе всего к SObjectizer, как мне кажется, системы обмена сообщениями. Например, TIBCO Randevouz. Или OpenSource библиотека Spread Toolkit.


Спасибо.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 30.04.07 16:18
Оценка: 41 (2)
Здравствуйте, Евгений Охотников, Вы писали:

Может это не сюда, но думаю, здесь тоже можно обсудить

<h3 class='formatter'>SObjectizer v.4.4 beta3 Notes</h3>

В первую очередь нужно избавляться от синхронизации

...
Может быть, подсчет ссылок получится заменить lock-free списками для событий/сообщений/агентов и это позволит избавится от синхронизации. Но это уже направление для дальнейших работ.


Если у тебя до этого дойдут руки, то я, возможно, мог бы чем-нибудь посодействовать...
Я имею в виду в плане lock-free структур данных.
Только, единственное, что было бы желательно сделать (но в прочем это было бо желательно сделать в любом случае) — сделать замеры производительности на многоядерной машине, в силу того, что они уже начинают входить в мейнстрим, а высокопроизводительные машины уже некоторое время многоядерные/многопроцессорные, и самое главное, что к этому всё неизбежно движется. Сейчас уже продаются 4-ёх ядерные процессоры, а самое интересное начнётся, когда появятся и будут в каждом ПК 8/16 и т.д. ядерные процессоры, и в каждом по несколько аппаратных контекстов lock-based структуры при переходе на многоядерные процессоры показывают практически нулевую масштабируемость, а lock-free близкую к линейной. Вот тут и начнётся самое интересное — как говорится, кто не спрятался, я не виноват
Поэтому даже сейчас было бы очень интересно поглядеть на результаты бенчмарков на 2 и 4 ядерных/процессорных машинах и оценить масштабируемость фреймворка.

Мой интерес какой? Что бы не было непонимания
Мне было бы интересно поглядеть на импакт внедрения lock-free структур в большие/реальные проекты, конкретно в цифрах, поглядеть как цифры будут зависеть от количества ядер, сравнить с lock-based структурами. Собственно получить опыт такого внедрения, поглядеть, возникают ли какие-то проблемы и т.д.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 30.04.07 17:13
Оценка:
Здравствуйте, remark, Вы писали:

E>>Нет, пока готовых рецептов для таких вещей нет. Но, я буду признателен, если подобные предложения будут поступать и, скажем фиксироваться в feature requests на SourceForge.


R>А там по-русски можно?


Можно. Пока там все осуждения идут на русском.

R>Ну вообще это будет не совсем честный реквест, т.к. я собственно пользователем sobjectizer не являюсь...


Может как раз реагирование на твои пожелания и позволят перевести тебя в число пользователей sobjectizer

E>>По поводу отсылки сообщения-ответа конкретному получателю могу навскидку предложить такой вариант:

E>>* в сообщении-запросе передавать отдельным полем имя агента-инициатора запроса;
E>>* ответное сообщение будет отсылаться целенаправлено тому агенту, имя которого было в запросе.

R>Понятно.


R>Я имею в виду что-то типа такого:


R>
R>void on_msg(msg& req)
R>{
R>  //...
R>  msg2 ack (...);
R>  answer_for(req, ack);
R>}
R>


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


Возможно, этого же можно достичь на прикладном уровне, введя некоторый базовый тип msg_with_request_id_t, в котором будет содержаться информация для отсылки ответа. И вспомогательный метод/свободную функцию answer_for, которая получив наследника msg_with_request_id_t сама выполняет отсылку ответного сообщения.

R>>>Имхо для систем именно компонентных и именно компонуемых из готовых компонетов, а я так понимаю, что это одно из серьёзных приемуществ агентных систем, такая функциональность была бы очень полезной...


E>>В чистом SObjectizer-е такой возможности нет. У меня были кое-какие мысли по поводу организации перехвата сообщений. Но удачного решения я не нашел


R>А в чём была проблема? В том как это реализовать с т.з. пользователя или как это реализовать внутри или прикрутить к существующему фреймворку?


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

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

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

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

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

E>>Возможность перехвата сообщений у нас сделана на основе отдельной библиотеки mbapi (message box api), которая построена поверх SObjectizer. Как раз там то, что ты описал и используется на полную катушку. И это действительно очень удобно и востребованно. Библиотека mbapi так же будет опубликована на SourceForge.


R>А на сколько она интегрируется с самим SObjectizer?

R>Т.е. как бы это сказать, насколько агенты mbapi являются агентами SObjectizer и наоборот. Т.е. mbapi — это полная обёртка над SObjectizer, как MFC над WinAPI или приложение пишется на SObjectizer и mbapi охватывает только некоторые части...

Скорее она просто базируется на SObjectizer, как Qt может быть построена над WinAPI
Изначально в mbapi было введено понятие почтальона, который мог доставлять mbapi-сообщение тому или иному получателю. Не обязательно получателем должен был быть агент. Но самым простым и удобным способом в SObjectizer приложениях оказалось делать получателей сообщений агентами, а mbapi-сообщения доставлять получателю в виде обычного сообщения.

Выглядит это все, к примеру, таким образом:
/*
  Демонстрационный агент, который периодически отсылает серверу сообщение
  handshake_t и обрабатывает ответ от сервера в виде сообщения handshake_reply_t.

  Типы handshake_t и handshake_reply_t -- это типы mbapi-сообщений.
*/
class    a_handshake_sender_t
    :    public so_4::rt::agent_t
    {
        typedef so_4::rt::agent_t    base_type_t;
    public :
        // Преобразование mbapi-сообщения в сообщение агента.
        typedef mbapi_3::router::so_msg_templ_t<
                        mbapi_3::handshake_reply_t,
                        mbapi_3::mbox_dest_t,
                        mbapi_3::mbox_dest_t >
                msg_handshake_reply;

        a_handshake_sender_t(
            const std::string & self_mbox_name )
            :    base_type_t( "a_handshake_sender" )
            ,    m_self_mbox_name( self_mbox_name )
            {
                // Регистрация почтальона, который все время, пока данный агент
                // зарегистрирован в SObjectizer, будет доставлять агенту
                // mbapi-сообщения в виде msg_handshake_reply.
                so_add_destroyable_traits(
                        new mbapi_3::router::so_msg_templ_postman_t<
                                        msg_handshake_reply >(
                            // Явно задается имя агента и сообщения
                            // для последующего использования в send_msg.
                            so_query_name(), "msg_handshake_reply",
                            // Этот анализатор будет определять, что полученное
                            // handshake_reply_t действительно адресовано нам,
                            // а не кому-нибудь другому.
                            mbapi_3::router::dest_equality_analyzer(
                                    mbapi_3::mbox_dest_t( self_mbox_name ) ) ) );

                so_add_destroyable_traits(
                        new mbapi_3_mbox::core::auto_publish_traits_t(
                                self_mbox_name ) );
            }

        virtual const char *
        so_query_type() const;

        virtual void
        so_on_subscription()
            {
                so_subscribe( "evt_tick", "msg_tick" );

                so_subscribe( "evt_handshake_reply", "msg_handshake_reply" );

                so_4::api::send_msg( so_query_name(), "msg_tick", 0, "",
                        3000, 3000 );
            }

        struct    msg_tick {};

        void
        evt_tick()
            {
                // Вот так отсылаются mbapi-сообщения.
                mbapi_3::router::route(
                        // Адрес получателя.
                        mbapi_3::mbox_dest_t( "server_box_1" ),
                        // Само тело сообщения.
                        mbapi_3::handshake_t(),
                        // Адрес оправителя. На этот адрес затем
                        // будет отсылаться ответ.
                        mbapi_3::mbox_dest_t( m_self_mbox_name ) );
            }

        void
        evt_handshake_reply(
            const msg_handshake_reply * cmd )
            {
                // Ответ получен, печатается имя его оправителя (т.е. сервера).
                std::cout << "received handshake reply from: " << *(cmd->reply_to())
                        << std::endl;
            }

    private :
        std::string    m_self_mbox_name;
    };


Вообще говоря, мне бы хотелось видеть SObjectizer как максимально простое ядро, на которое дополнительная функциональность навешивается в виде дополнительных библиотек. Это можно видеть уже сейчас -- на SourceForge уже опубликованы SoAltChannel, который позволяет переключать каналы по резервным IP адресам, и SoSysConf, который позволяет собирать SObjectizer приложения как из конструктора. Ждут своей очереди к публикации, например, Generic Monitoring Tools (Gemont) для организации удаленного мониторинга SObjectizer приложений и mbapi для более сложных форм доставки и обработки сообщений.

Как бы повторяю ошибку Страуструпа -- зачем включать в ядро то, что можно поместить в библиотеки?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 30.04.07 17:13
Оценка:
Здравствуйте, remark, Вы писали:

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

R>Я имею в виду в плане lock-free структур данных.

Ok, спасибо. Буду, как говориться, держать в памяти.

Пользуясь случаем хочу, так сказать, прозондировать почву: как бы лично ты отнесся к появлению SObjectizer для D или, скажем, Scala?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 30.04.07 17:23
Оценка:
Здравствуйте, eao197, Вы писали:

E>Пользуясь случаем хочу, так сказать, прозондировать почву: как бы лично ты отнесся к появлению SObjectizer для D или, скажем, Scala?


Честно говоря, никак

Про D, конечно, слышал и видел код... если он станет промышленным языком, то другое дело, но это имхо пока сомнительно...
Про Scala аналогично...

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

Где это, наверное, надо, так это как ни странно — С, но на него, наверное, печально портировать с С++


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 30.04.07 17:35
Оценка:
Здравствуйте, eao197, Вы писали:

E>Возможно, этого же можно достичь на прикладном уровне, введя некоторый базовый тип msg_with_request_id_t, в котором будет содержаться информация для отсылки ответа. И вспомогательный метод/свободную функцию answer_for, которая получив наследника msg_with_request_id_t сама выполняет отсылку ответного сообщения.


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




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

Ясно.


E>Вообще говоря, мне бы хотелось видеть SObjectizer как максимально простое ядро, на которое дополнительная функциональность навешивается в виде дополнительных библиотек. Это можно видеть уже сейчас -- на SourceForge уже опубликованы SoAltChannel, который позволяет переключать каналы по резервным IP адресам, и SoSysConf, который позволяет собирать SObjectizer приложения как из конструктора. Ждут своей очереди к публикации, например, Generic Monitoring Tools (Gemont) для организации удаленного мониторинга SObjectizer приложений и mbapi для более сложных форм доставки и обработки сообщений.


E>Как бы повторяю ошибку Страуструпа -- зачем включать в ядро то, что можно поместить в библиотеки?


Опять же опять всё упирается в то, насколько фреймворк предоставляет возможности для расширения и хуки...
Но в целом, я понял...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 30.04.07 17:59
Оценка:
Здравствуйте, remark, Вы писали:

R>Про D, конечно, слышал и видел код... если он станет промышленным языком, то другое дело, но это имхо пока сомнительно...

R>Про Scala аналогично...

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

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


Вопрос потрирования никто и не снимал Да и речь шла о других языках, на которых биты из тактов не выжимают, а XML-ями направо и налево размениваются
Просто в все упирается в простой факт: чем дальше, тем дороже обходится развитие C++ проектов -- новых людей приходится C++у с нуля учить, да и без особого энтузиазма он изучается
А более современными языками пользоваться приятнее, есть надежда, что и новых людей им обучать будет проще.

R>Где это, наверное, надо, так это как ни странно — С, но на него, наверное, печально портировать с С++


Не, это уже без меня Я слишком OOP addicted man.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 30.04.07 19:05
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Про D, конечно, слышал и видел код... если он станет промышленным языком, то другое дело, но это имхо пока сомнительно...

R>>Про Scala аналогично...

E>А сейчас что с D, что со Scala ситуация такая -- сами по себе промышленными языками они не станут, их можно только таковыми сделать


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


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


E>Вопрос потрирования никто и не снимал Да и речь шла о других языках, на которых биты из тактов не выжимают, а XML-ями направо и налево размениваются

E>Просто в все упирается в простой факт: чем дальше, тем дороже обходится развитие C++ проектов -- новых людей приходится C++у с нуля учить, да и без особого энтузиазма он изучается
E>А более современными языками пользоваться приятнее, есть надежда, что и новых людей им обучать будет проще.

Ну фиг знает — время расставит точки...
Идея простого промышленного языка — имхо фикция...
В сложности современных систем язык является величиной меньшего порядка малости... опять же имхо... ну ладно, с этим уже надо идти в Философию


R>>Где это, наверное, надо, так это как ни странно — С, но на него, наверное, печально портировать с С++


E>Не, это уже без меня Я слишком OOP addicted man.


А что мешает на С OOP применять?
Вроде недавно в С/С++ проскакивала ссылка на книгу типа "ООП на С"


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 01.05.07 07:26
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


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

R>>Я имею в виду в плане lock-free структур данных.

E>Ok, спасибо. Буду, как говориться, держать в памяти.


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

А какие структуры сейчас являются узким местом?
Могу предположить, что, естественно, fifo очереди для сообщений. Так же скорее всего какие-нибудь "глобальные" данные, типа настроек или кэшей. Возможно какие-то lifo стеки. Скорее всего ещё какие-нибудь отображения hash/map... Что-то ещё?



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.05.07 08:21
Оценка:
Здравствуйте, remark, Вы писали:

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

R>>>Я имею в виду в плане lock-free структур данных.

E>>Ok, спасибо. Буду, как говориться, держать в памяти.


R>А это сейчас в каком статусе? Я так понимаю в статусе просто идеи. Или уже чётко решено, что в ближайшие месяцы надо ещё повышать производительность?


Нет, пока понятно, что в версию 4.4 реализация на основе lock-free алгоритмов не попадет. Сейчас задача в том, чтобы повышать производительность сетевых обменов, но не отсылки сообщений внутри SObjectizer.

R>А какие структуры сейчас являются узким местом?

R>Могу предположить, что, естественно, fifo очереди для сообщений. Так же скорее всего какие-нибудь "глобальные" данные, типа настроек или кэшей. Возможно какие-то lifo стеки. Скорее всего ещё какие-нибудь отображения hash/map... Что-то ещё?

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

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

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[5]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 01.05.07 09:01
Оценка:
Здравствуйте, eao197, Вы писали:

R>>А какие структуры сейчас являются узким местом?

R>>Могу предположить, что, естественно, fifo очереди для сообщений. Так же скорее всего какие-нибудь "глобальные" данные, типа настроек или кэшей. Возможно какие-то lifo стеки. Скорее всего ещё какие-нибудь отображения hash/map... Что-то ещё?

E>Нет, узким местом являются не структуры. А счетчики ссылок на экземпляры сообщений и агентов. Без этих счетчиков нельзя точно определять моменты удаления сообщений и дерегистрации агентов. А для корректного изменения счетчиков требуется синхронизация на mutex-е, именно она все и тормозит. Причем сейчас не представляется возможным использовать Interlocked-операции инкремента и декремента.


Хм... а почему нельзя использовать Interlocked-операции?


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


Интересно...

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


Сборка мусора — это тоже не панацея — там своих проблем хватает...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[6]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 01.05.07 09:30
Оценка:
Здравствуйте, remark, Вы писали:

E>>Нет, узким местом являются не структуры. А счетчики ссылок на экземпляры сообщений и агентов. Без этих счетчиков нельзя точно определять моменты удаления сообщений и дерегистрации агентов. А для корректного изменения счетчиков требуется синхронизация на mutex-е, именно она все и тормозит. Причем сейчас не представляется возможным использовать Interlocked-операции инкремента и декремента.


R>Хм... а почему нельзя использовать Interlocked-операции?


Потому что изменение счетчика ссылок на сообщение должно выполняться в одной же транзакции с изменением счетчика ссылок на агента-владельца. А иногда и еще какой-то счетчик задействуется (если не забыл ничего). Т.е. за раз нужно изменять сразу несколько ссылок.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 02.05.07 04:56
Оценка: 38 (1) +1 :)
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


E>>>Нет, узким местом являются не структуры. А счетчики ссылок на экземпляры сообщений и агентов. Без этих счетчиков нельзя точно определять моменты удаления сообщений и дерегистрации агентов. А для корректного изменения счетчиков требуется синхронизация на mutex-е, именно она все и тормозит. Причем сейчас не представляется возможным использовать Interlocked-операции инкремента и декремента.


R>>Хм... а почему нельзя использовать Interlocked-операции?


E>Потому что изменение счетчика ссылок на сообщение должно выполняться в одной же транзакции с изменением счетчика ссылок на агента-владельца. А иногда и еще какой-то счетчик задействуется (если не забыл ничего). Т.е. за раз нужно изменять сразу несколько ссылок.


А почему это должно быть именно в одной транзакции? Почему никто не должен видеть эти счётчики в рассогласованных состояниях? Ведь с reference counting'ом обычно так — или в счётчике не ноль и тогда собственно пофигу что, т.к. объект не удаляется, или в счётчике 0, и тогда вобщем-то тоже пофигу, т.к. объект удаляется...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 02.05.07 05:42
Оценка:
Здравствуйте, remark, Вы писали:

E>>Потому что изменение счетчика ссылок на сообщение должно выполняться в одной же транзакции с изменением счетчика ссылок на агента-владельца. А иногда и еще какой-то счетчик задействуется (если не забыл ничего). Т.е. за раз нужно изменять сразу несколько ссылок.


R>А почему это должно быть именно в одной транзакции? Почему никто не должен видеть эти счётчики в рассогласованных состояниях? Ведь с reference counting'ом обычно так — или в счётчике не ноль и тогда собственно пофигу что, т.к. объект не удаляется, или в счётчике 0, и тогда вобщем-то тоже пофигу, т.к. объект удаляется...


Интересно, нужно будет об этом подумать.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.05.07 11:25
Оценка:
Здравствуйте, remark, Вы писали:

R>>>Хм... а почему нельзя использовать Interlocked-операции?


E>>Потому что изменение счетчика ссылок на сообщение должно выполняться в одной же транзакции с изменением счетчика ссылок на агента-владельца. А иногда и еще какой-то счетчик задействуется (если не забыл ничего). Т.е. за раз нужно изменять сразу несколько ссылок.


R>А почему это должно быть именно в одной транзакции? Почему никто не должен видеть эти счётчики в рассогласованных состояниях? Ведь с reference counting'ом обычно так — или в счётчике не ноль и тогда собственно пофигу что, т.к. объект не удаляется, или в счётчике 0, и тогда вобщем-то тоже пофигу, т.к. объект удаляется...


Я тут сваял тестик с некоторой имитацией подсчета ссылок в SObjectizer. Он делает подсчет ссылок на основе блокировке на mutex-е (фактически, critical section в Windows) и на основе atomic-операций. Дело в том, что в SObjectizer нужно увеличивать не один счетчик, а четыре. Поэтому интересно было сравнить, насколько четыре atomic-op выгоднее, чем один mutex. Оказались, что не выгоднее.

Вот замеры на Pentium-M 1.5GHz (512Mb, WinXP-SP2):
objects: 1, thread_per_object: 4, cycles: 1000000
refcount_by_mutex: 0.578
refcount_by_atomic_op: 0.89
objects: 10, thread_per_object: 4, cycles: 1000000
refcount_by_mutex: 6.062
refcount_by_atomic_op: 8.842
objects: 100, thread_per_object: 4, cycles: 1000000
refcount_by_mutex: 59.633
refcount_by_atomic_op: 88.537


Вот замеры на двух-процессорной 2 х Xeon 3.2 (2G RAM, Win2003):
objects: 1, thread_per_object: 4, cycles: 1000000
refcount_by_mutex: 1.5
refcount_by_atomic_op: 1.969
objects: 10, thread_per_object: 4, cycles: 1000000
refcount_by_mutex: 4.313
refcount_by_atomic_op: 9.484
objects: 100, thread_per_object: 4, cycles: 1000000
refcount_by_mutex: 25.548
refcount_by_atomic_op: 47.469


На двух-процессорной машине при увеличении количества нитей вариант на atomic-op проигрывает гораздо больше варианту с mutex-ом, чем на однопроцессорной (разрыв больше).

У тебя есть возможность прогнать этот тест на 4-х процессорной машине? (А то в моем распоряжении только 2-х процессорные). Требуется ACE, я использовал ACE 5.5.6.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 13:20
Оценка:
Здравствуйте, eao197, Вы писали:

E>Я тут сваял тестик с некоторой имитацией подсчета ссылок в SObjectizer. Он делает подсчет ссылок на основе блокировке на mutex-е (фактически, critical section в Windows) и на основе atomic-операций. Дело в том, что в SObjectizer нужно увеличивать не один счетчик, а четыре. Поэтому интересно было сравнить, насколько четыре atomic-op выгоднее, чем один mutex. Оказались, что не выгоднее.


В принципе это достаточно ожидаемый результат, т.к. основной вклад в стоимость операций вносят atomic операции.
При использовании мьютекса это 2 операции. При использовании reference counting на atomic операциях это соотв. 4...

E>На двух-процессорной машине при увеличении количества нитей вариант на atomic-op проигрывает гораздо больше варианту с mutex-ом, чем на однопроцессорной (разрыв больше).


По той же причине...

E>У тебя есть возможность прогнать этот тест на 4-х процессорной машине? (А то в моем распоряжении только 2-х процессорные). Требуется ACE, я использовал ACE 5.5.6.


Нет, 4-ёх ядерной у меня нет...

А тебя в SObjectizer мьютексы тоже локальные используются или один глобальный? Если один глобальный, то в тесте надо тоже сделать один на все объекты, а не на каждый объект по мьютексу...

А сколько в SObjectizer в среднем за один раз счётчиков изменяется? Может меньше 4? Если сделать тест с 2 или 3 счётчиками, то результаты тоже должны поменяться...

Ну в принципе, что я могу сказать... надо смотреть конкретную ситуацию... в общем случае задача — уменьшать кол-во atomic операций, уменьшать кол-во барьеров памяти, уменьшать конкуренцию на кэш-линии, уменьшать доступ к глобальным данным и т.д.
Вот так-вот просто заменить — ничего хорошего не получится. К сожалению, сейчас в сети множество таких "lock-free" алгоритмов, для которых требуется по 5-6 atomic операций — конечно они убивают всё производительность на корню.
Ситуация такая: при использовании мьютексов всё жестко определено — у тебя будет 2 atomic операции + возможность очень дорогой блокировки. при использовании lock-free ничего не детерминировано — ты можешь сделать очень плохой алгоритм, можешь сделать такой же как на мьютексах, можешь при определённом везении и знании сделать в конкретной ситуации алгоритм, который будет летать — иметь 0 atomic операций, не обращаться к глобальным данным, масштабироваться линейно и т.д... но это в любом случае будет кровавый поединок человека и машины

Что можно делать: амортизировать кол-во дорогих операций (добавлять thread-local кэши, выполнять дорогие операции не каждый раз и т.д.), локализовать данные (делать данные по возможности thread-local, или one-thread-write), локализовывать потоки по процессорам, добавлять короткие пути для типовых ситуаций, группировать счётчики референсов и т.д. и т.п.
Простор широчайший, а что делать конкретно — надо смотреть конкретную ситуацию...

А в коде этот референс каунтинг локализован? Я смогу более-менее быстро окинуть его взглядом? Можешь скажешь куда смотреть.
Или может даже лучше ты как-то обрисуешь в общих чертах, что там происходит? Ну я так понимаю, что естественно для сообщений есть счётчик, устанавливается он при отправке сообщений, и уменьшается при обработке каждым агентом. Так? А ещё с чем связаны счётчики? С агентами? А когда они изменяются? Откуда берётся 4 счётчика?



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.05.07 13:55
Оценка:
Здравствуйте, remark, Вы писали:

R>А тебя в SObjectizer мьютексы тоже локальные используются или один глобальный? Если один глобальный, то в тесте надо тоже сделать один на все объекты, а не на каждый объект по мьютексу...


Глобальные мьютексы используются (если вспоминать навскидку) для:
* защиты ядра SObjectizer и его системного словаря при выполнении таких операций, как send_msg, register_coop, deregister_coop и пр.;
* при выделении памяти в стандратной библиотеке C++.

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

R>А сколько в SObjectizer в среднем за один раз счётчиков изменяется? Может меньше 4? Если сделать тест с 2 или 3 счётчиками, то результаты тоже должны поменяться...


Думаю, что таки не меньше 4-х:
* один счетчик для агента;
* один счетчик для сообщения;
* один счетчик для события;
* счетчики для сообщений и событий инкрементируются и декрементируются при помещении некоторых объектов в некоторые контейнеры (см. ниже).

R>Ситуация такая: при использовании мьютексов всё жестко определено — у тебя будет 2 atomic операции + возможность очень дорогой блокировки. при использовании lock-free ничего не детерминировано — ты можешь сделать очень плохой алгоритм, можешь сделать такой же как на мьютексах, можешь при определённом везении и знании сделать в конкретной ситуации алгоритм, который будет летать — иметь 0 atomic операций, не обращаться к глобальным данным, масштабироваться линейно и т.д... но это в любом случае будет кровавый поединок человека и машины


Я бы добавил сюда еще и потенциальные проблемы с переносимостью atomic-операций. На x86 есть инструкции для их поддержке. А вот на каких-нибудь Sun-ах или MIPS-ах с этим дело как обстоит?

R>А в коде этот референс каунтинг локализован? Я смогу более-менее быстро окинуть его взглядом? Можешь скажешь куда смотреть.

R>Или может даже лучше ты как-то обрисуешь в общих чертах, что там происходит? Ну я так понимаю, что естественно для сообщений есть счётчик, устанавливается он при отправке сообщений, и уменьшается при обработке каждым агентом. Так? А ещё с чем связаны счётчики? С агентами? А когда они изменяются? Откуда берётся 4 счётчика?

Принцип такой:
* при отсылке сообщения создается объект so_4::rt::msg_data_t. Он создает объект so_4::rt::impl::msg_data_impl_t;
* когда создается объект so_4::rt::impl::msg_data_impl_t (т.е. описатель экземпляра сообщения внутри SObjectizer), то увеличивается счетчик ссылок на сам msg_data_impl_t, а так же на соответствующего агента (объект so_4::rt::impl::agent_wrapper_base_t);
* при копировании so_4::rt::msg_data_t инкрементируются и декрементируются счетчики на so_4::rt::impl::msg_data_impl_t;
* при диспетчеризации заявок, полученных при отсылке сообщения, создаются объекты so_4::rt::event_data_t. Которые содержат в себе объекты, производные от so_4::rt::impl::event_data_impl_t;
* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;
* так же so_4::rt::impl::evt_data_impl_t содежат ссылку на msg_data_impl_t и для сохранения ее корректности увеличивают количество ссылок на msg_data_impl_t (с соответствующим увеличением количества ссылок на агента).

Собственно, изменением количества ссылок управляют методы: msg_data_impl_t::inc_ref_count, dec_ref_count; event_data_impl_t::inc_ref_count, dec_ref_count; agent_wrapper_base_t::inc_ref_count, dec_ref_count.

Схема запутанная, но пять лет назад я не смог придумать ничего лучше, поскольку объекты msg_data_t, event_data_t всю эту кухню скрывают внутри себя, что позволяет легко манипулировать объектами msg_data_t, event_data_t -- а это было очень важно чтобы получить корректно работающую версию SObjectizer.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 15:04
Оценка:
Здравствуйте, eao197, Вы писали:

E>Принцип такой:

E>* при отсылке сообщения создается объект so_4::rt::msg_data_t. Он создает объект so_4::rt::impl::msg_data_impl_t;
E>* когда создается объект so_4::rt::impl::msg_data_impl_t (т.е. описатель экземпляра сообщения внутри SObjectizer), то увеличивается счетчик ссылок на сам msg_data_impl_t, а так же на соответствующего агента (объект so_4::rt::impl::agent_wrapper_base_t);
E>* при копировании so_4::rt::msg_data_t инкрементируются и декрементируются счетчики на so_4::rt::impl::msg_data_impl_t;
E>* при диспетчеризации заявок, полученных при отсылке сообщения, создаются объекты so_4::rt::event_data_t. Которые содержат в себе объекты, производные от so_4::rt::impl::event_data_impl_t;
E>* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;
E>* так же so_4::rt::impl::evt_data_impl_t содежат ссылку на msg_data_impl_t и для сохранения ее корректности увеличивают количество ссылок на msg_data_impl_t (с соответствующим увеличением количества ссылок на агента).


Я правильно понимаю ситуацию, что увеличение/уменьшение референса для агента при создании/удалении сообщений и событий необходимо, что бы агент не умер пока существуют его сообщения и события?
При этом агент держит сам на себя один референс, и удаляет его, когда пользователь говорит удалить агента. При этом агент может просуществовать немного дольше — пока живут его сообщения и события?
Соответственно увеличение/уменьшение референса для сообщений при создании/удалении событий необходимо, что бы сообщение не умерло пока не обработаны все связанные с ним события?


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[12]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.05.07 15:10
Оценка:
Здравствуйте, remark, Вы писали:

R>Я правильно понимаю ситуацию, что увеличение/уменьшение референса для агента при создании/удалении сообщений и событий необходимо, что бы агент не умер пока существуют его сообщения и события?


Да.

R>При этом агент держит сам на себя один референс, и удаляет его, когда пользователь говорит удалить агента. При этом агент может просуществовать немного дольше — пока живут его сообщения и события?


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

R>Соответственно увеличение/уменьшение референса для сообщений при создании/удалении событий необходимо, что бы сообщение не умерло пока не обработаны все связанные с ним события?


Да. С самими событиями аналогичная ситуация -- событие не должно исчезнуть, пока оно хоть кем-то используется (например, стоит в очереди диспетчера или уже обрабатывается агентом).


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 15:40
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>А тебя в SObjectizer мьютексы тоже локальные используются или один глобальный? Если один глобальный, то в тесте надо тоже сделать один на все объекты, а не на каждый объект по мьютексу...


E>Глобальные мьютексы используются (если вспоминать навскидку) для:

E>* защиты ядра SObjectizer и его системного словаря при выполнении таких операций, как send_msg, register_coop, deregister_coop и пр.;

Если изменение системного словаря происходит редко, то это можно очень эффективно разрешить — обращения к словарю не будут затрагивать мьютекс, атомарных операций, блокировок и т.д. Доступ на чтение будет практически бесплатным.
Трейдофф: при изменении системного словаря придётся его копировать. По крайне мере частично.

E>* при выделении памяти в стандратной библиотеке C++.


Тут можно так сделать — для объектов, которые выделяются в больших количествах (сообщения/события), можно сделать эффективные кэширующие неблокирующие схемы, которые тоже не будут затрагивать мьютексов и атомарных операций.
Трейдофф: большее потребление памяти. Ну, если надо быстро, то кэшировать придётся в любом случае — тут стандартный размен памяти на скорость.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 15:51
Оценка:
Здравствуйте, eao197, Вы писали:

E>Я бы добавил сюда еще и потенциальные проблемы с переносимостью atomic-операций. На x86 есть инструкции для их поддержке. А вот на каких-нибудь Sun-ах или MIPS-ах с этим дело как обстоит?


Это как раз принципиальной проблемы точно не составляет.
Так или иначе аналоги этих операций есть на всех SMP системах — иначе бы там и мьютекса не сделать.
На большинстве машин примитивы достаточно похожи на x86, на каких-то примитивы немного другие, но базовые вещи, такие как референс каунтинг или мьютекс, точно сделать можно.
Да, портировать, конечно, будет сложнее. Но в идеале можно тоже взять готовую библиотеку портированных примитивов и использовать её. Вот ты сам приводил в примере атомарные операции в ACE...
Ну и в любом случае эти все вещи можно достаточно чётко локализовать в классах типа atomic_ref_counter, thread_shared_ptr, fifo_queue и т.д. И уже портровать исключительно их, на крайний случай для какой-то платформы можно сделать и на мьютексе.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 16:36
Оценка:
Здравствуйте, eao197, Вы писали:

E>Принцип такой:

E>* при отсылке сообщения создается объект so_4::rt::msg_data_t. Он создает объект so_4::rt::impl::msg_data_impl_t;
E>* когда создается объект so_4::rt::impl::msg_data_impl_t (т.е. описатель экземпляра сообщения внутри SObjectizer), то увеличивается счетчик ссылок на сам msg_data_impl_t, а так же на соответствующего агента (объект so_4::rt::impl::agent_wrapper_base_t);
E>* при копировании so_4::rt::msg_data_t инкрементируются и декрементируются счетчики на so_4::rt::impl::msg_data_impl_t;
E>* при диспетчеризации заявок, полученных при отсылке сообщения, создаются объекты so_4::rt::event_data_t. Которые содержат в себе объекты, производные от so_4::rt::impl::event_data_impl_t;
E>* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;
E>* так же so_4::rt::impl::evt_data_impl_t содежат ссылку на msg_data_impl_t и для сохранения ее корректности увеличивают количество ссылок на msg_data_impl_t (с соответствующим увеличением количества ссылок на агента).

E>Схема запутанная, но пять лет назад я не смог придумать ничего лучше, поскольку объекты msg_data_t, event_data_t всю эту кухню скрывают внутри себя, что позволяет легко манипулировать объектами msg_data_t, event_data_t -- а это было очень важно чтобы получить корректно работающую версию SObjectizer.


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

Сходу:

Вот это избыточно:
E>* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;
Т.к. событие держит сообщение, а сообщение держит агента — следовательно событию держать агента уже не обязательно.

Вот это тоже вроде как избыточно, т.к. агента мы уже держим с помощью самого сообщения:
* так же so_4::rt::impl::evt_data_impl_t содежат ссылку на msg_data_impl_t и для сохранения ее корректности увеличивают количество ссылок на msg_data_impl_t (с соответствующим увеличением количества ссылок на агента).

Потом я так понимаю, что ты используешь хендлы разделяемых объектов, которые при создании/копировании увеличивают счётчик для объекта, а в деструкторе уменьшают его. Неинтрузивное владение и неинтрузивные контейнеры, конечно, очень удобно и просто, но приводит к лишним изменениям счётчика.

На первый взгляд видится как-то так:
Посылка нового сообщения:
— создаёшь тело сообщения
— создаёшь тело события
— т.к. рутинг происходит сразу, сразу устанавливаешь у события счётчик в нужное число
— у сообщения нет смысла устанавливать счётчик, т.к. оно будет жить пока живёт событие
— раскладываешь события по очередям агентов
— когда агент заканчивает обработку события, то он уменьшает счётчик события
— если при этом счётчик события достигает 0, то удаляется событие и сообщение

— при этом каждый раз трогать счётчик агента нет смысла — можно положить в tls агрегированный счётчик использования этого агента всеми сообщениями и событиями этого треда, т.о. сам разделяемый счётчик агента будет декрементироваться только один раз, когда в данном треде никто больше его не использует (с агрегированным счётчиком в tls можно работать простыми декрементами/инкрементами — ничего защищать не надо)

— плюс можно аналогично агрегировать работу со счётчиком события по потокам, т.е. только последняя обработка события в потоке будет уменьшать его счётчик

Это, конечно, очень схематично. Наверняка в реальнсти всё будет сложнее. Да и тут вопросов много — например, как эффективно хранить в tls агрегированные счётчики для всех агентов. Но тем не менее, я думаю, что что-то похожее можно сделать.

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

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


Стоп. Я наверное тут что-то напутал. Ну ладно уже написал — удалять жалко
При отсылке сообщения надо инкрементировать счётчик не только для агента, которому принадлежит сообщение, но и тем, кому сообщение отправляется. Правильно? Ну всё равно временем жизни агентов можно управлять агрегированно на уровне потоков — только когда никто в потоке не интересуется агентом, декрементируем у него счётчик.
С событиями я похоже тоже что-то напутал — т.к. для одного сообщения создаётся не одно событие, а множество. Правильно? Тоже всё равно можно что-нибудь агрегировать по потокам и убрать избыточные инкремены/декременты.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 16:44
Оценка:
Здравствуйте, eao197, Вы писали:

Вот это я что-то не очень понял:

E>* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;


evt_data_impl_t сам на себя счётчик увеличивает?

И про агентов я запутался — тут же несколько агентов принимает участие — один, которому принадлежит сообщение, и остальные, которые обрабатывают события. Правильно?




E>* при отсылке сообщения создается объект so_4::rt::msg_data_t. Он создает объект so_4::rt::impl::msg_data_impl_t;


Вот тут вот мы увеличиваем счётчик агента, которому принадлежит сообщение:

E>* когда создается объект so_4::rt::impl::msg_data_impl_t (т.е. описатель экземпляра сообщения внутри SObjectizer), то увеличивается счетчик ссылок на сам msg_data_impl_t, а так же на соответствующего агента (объект so_4::rt::impl::agent_wrapper_base_t);


E>* при копировании so_4::rt::msg_data_t инкрементируются и декрементируются счетчики на so_4::rt::impl::msg_data_impl_t;

E>* при диспетчеризации заявок, полученных при отсылке сообщения, создаются объекты so_4::rt::event_data_t. Которые содержат в себе объекты, производные от so_4::rt::impl::event_data_impl_t;

А вот тут вот уже на того агента, который будет обрабатывать событие:

E>* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;


А вот тут опять на первого:

E>* так же so_4::rt::impl::evt_data_impl_t содежат ссылку на msg_data_impl_t и для сохранения ее корректности увеличивают количество ссылок на msg_data_impl_t (с соответствующим увеличением количества ссылок на агента).


Правильно?



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[12]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.05.07 17:02
Оценка:
Здравствуйте, remark, Вы писали:

E>>* защиты ядра SObjectizer и его системного словаря при выполнении таких операций, как send_msg, register_coop, deregister_coop и пр.;


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

R>Трейдофф: при изменении системного словаря придётся его копировать. По крайне мере частично.

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

E>>* при выделении памяти в стандратной библиотеке C++.


R>Тут можно так сделать — для объектов, которые выделяются в больших количествах (сообщения/события), можно сделать эффективные кэширующие неблокирующие схемы, которые тоже не будут затрагивать мьютексов и атомарных операций.

R>Трейдофф: большее потребление памяти. Ну, если надо быстро, то кэшировать придётся в любом случае — тут стандартный размен памяти на скорость.

Это можно решать не задействуя внутренности SObjectizer -- пользователь может сам реализовывать new/delete для своих сообщений.

А память в самом SObjectizer нужно будет оптимизировать когда именно она станет узким местом.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.05.07 17:19
Оценка:
Здравствуйте, remark, Вы писали:

E>>* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;


R>evt_data_impl_t сам на себя счётчик увеличивает?


Очепятался -- когда создается so_4::rt::event_data_t.

R>И про агентов я запутался — тут же несколько агентов принимает участие — один, которому принадлежит сообщение, и остальные, которые обрабатывают события. Правильно?


Да.


E>>* при отсылке сообщения создается объект so_4::rt::msg_data_t. Он создает объект so_4::rt::impl::msg_data_impl_t;


R>Вот тут вот мы увеличиваем счётчик агента, которому принадлежит сообщение:


E>>* когда создается объект so_4::rt::impl::msg_data_impl_t (т.е. описатель экземпляра сообщения внутри SObjectizer), то увеличивается счетчик ссылок на сам msg_data_impl_t, а так же на соответствующего агента (объект so_4::rt::impl::agent_wrapper_base_t);


E>>* при копировании so_4::rt::msg_data_t инкрементируются и декрементируются счетчики на so_4::rt::impl::msg_data_impl_t;

E>>* при диспетчеризации заявок, полученных при отсылке сообщения, создаются объекты so_4::rt::event_data_t. Которые содержат в себе объекты, производные от so_4::rt::impl::event_data_impl_t;

R>А вот тут вот уже на того агента, который будет обрабатывать событие:


E>>* когда создается объект so_4::rt::impl::evt_data_impl_t (т.е. описатель одной заявки для события), то увеличивается счетчик ссылок на сам evt_data_impl_t и на соответствующего агента;


R>А вот тут опять на первого:


E>>* так же so_4::rt::impl::evt_data_impl_t содежат ссылку на msg_data_impl_t и для сохранения ее корректности увеличивают количество ссылок на msg_data_impl_t (с соответствующим увеличением количества ссылок на агента).


R>Правильно?


Да.

Еще дополнение для полноты картины: сообщение может быть отложенным и/или переодическим. В этом случае еще msg_data_t уходит диспетчеру в нить таймера.

По поводу tls -- тогда усложняется подсчет количества ссылок на агента при дерегистрации.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 17:22
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


E>>>* защиты ядра SObjectizer и его системного словаря при выполнении таких операций, как send_msg, register_coop, deregister_coop и пр.;


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

R>>Трейдофф: при изменении системного словаря придётся его копировать. По крайне мере частично.

E>Это будет довольно накладно, когда агентов будет тысячи, а создаваться и удаляться они будут на каждый чих (как процессы в Erlang). В ряде проектов у нас так и делается -- агенты создаются на каждую транзацию, иногда сотни в секунду.


Ну это смотря насколько частично копировать
Если он часто изменяется, то, конечно, надо другое решение...


E>>>* при выделении памяти в стандратной библиотеке C++.


R>>Тут можно так сделать — для объектов, которые выделяются в больших количествах (сообщения/события), можно сделать эффективные кэширующие неблокирующие схемы, которые тоже не будут затрагивать мьютексов и атомарных операций.

R>>Трейдофф: большее потребление памяти. Ну, если надо быстро, то кэшировать придётся в любом случае — тут стандартный размен памяти на скорость.

E>Это можно решать не задействуя внутренности SObjectizer -- пользователь может сам реализовывать new/delete для своих сообщений.


Внутри тоже, наверное, что-то должно часто создаваться/удаляться — события, например...

E>А память в самом SObjectizer нужно будет оптимизировать когда именно она станет узким местом.


Ну это без вопросов...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[13]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 17:29
Оценка:
Здравствуйте, eao197, Вы писали:

E>По поводу tls -- тогда усложняется подсчет количества ссылок на агента при дерегистрации.


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

А чем tls усложняет? Это же просто кэширование. Т.е. можно 100 раз вызвать инкремент, потом 100 раз декремент. А можно с тем же успехом 1 раз вызвать инкремент, потом 99 раз посчитать в tls, а потом 1 раз вызвать декремент.
Т.е. с т.з. агента ничего не меняется — просто как будто его только один объект использует из потока...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[14]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.05.07 18:39
Оценка:
Здравствуйте, remark, Вы писали:

E>>По поводу tls -- тогда усложняется подсчет количества ссылок на агента при дерегистрации.


R>Я понимаю, что могут возникать какие-то детали, которые перечёркивают какую-то идею накорню. Поэтому я пока говорю больше в ключе "что можно сделать вообще"... Я понимаю, что всё не так просто...


R>А чем tls усложняет? Это же просто кэширование. Т.е. можно 100 раз вызвать инкремент, потом 100 раз декремент. А можно с тем же успехом 1 раз вызвать инкремент, потом 99 раз посчитать в tls, а потом 1 раз вызвать декремент.

R>Т.е. с т.з. агента ничего не меняется — просто как будто его только один объект использует из потока...

С точки зрения агента не меняется, меняется с точки зрения системного словаря и логики инкрементирования количества ссылок.

Тут с событиями для tls другой минус -- если не ошибаюсь, то event_data_t распихивается по очередям диспетчера совсем на другой нити, чем затем будет выполняться (на нити, на которой вызывался send_msg).

Хотя идея интересная. С ходу, правда, красивое и простое решение пока не вырисовывается, но можно покурить



SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 07.05.07 22:23
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>>>Хм... а почему нельзя использовать Interlocked-операции?


E>>>Потому что изменение счетчика ссылок на сообщение должно выполняться в одной же транзакции с изменением счетчика ссылок на агента-владельца. А иногда и еще какой-то счетчик задействуется (если не забыл ничего). Т.е. за раз нужно изменять сразу несколько ссылок.


R>>А почему это должно быть именно в одной транзакции? Почему никто не должен видеть эти счётчики в рассогласованных состояниях? Ведь с reference counting'ом обычно так — или в счётчике не ноль и тогда собственно пофигу что, т.к. объект не удаляется, или в счётчике 0, и тогда вобщем-то тоже пофигу, т.к. объект удаляется...


E>Я тут сваял тестик с некоторой имитацией подсчета ссылок в SObjectizer. Он делает подсчет ссылок на основе блокировке на mutex-е (фактически, critical section в Windows) и на основе atomic-операций. Дело в том, что в SObjectizer нужно увеличивать не один счетчик, а четыре. Поэтому интересно было сравнить, насколько четыре atomic-op выгоднее, чем один mutex. Оказались, что не выгоднее.


E>Вот замеры на Pentium-M 1.5GHz (512Mb, WinXP-SP2):

E>
E>objects: 1, thread_per_object: 4, cycles: 1000000
E>refcount_by_mutex: 0.578
E>refcount_by_atomic_op: 0.89
E>objects: 10, thread_per_object: 4, cycles: 1000000
E>refcount_by_mutex: 6.062
E>refcount_by_atomic_op: 8.842
E>objects: 100, thread_per_object: 4, cycles: 1000000
E>refcount_by_mutex: 59.633
E>refcount_by_atomic_op: 88.537
E>


E>Вот замеры на двух-процессорной 2 х Xeon 3.2 (2G RAM, Win2003):

E>
E>objects: 1, thread_per_object: 4, cycles: 1000000
E>refcount_by_mutex: 1.5
E>refcount_by_atomic_op: 1.969
E>objects: 10, thread_per_object: 4, cycles: 1000000
E>refcount_by_mutex: 4.313
E>refcount_by_atomic_op: 9.484
E>objects: 100, thread_per_object: 4, cycles: 1000000
E>refcount_by_mutex: 25.548
E>refcount_by_atomic_op: 47.469
E>


E>На двух-процессорной машине при увеличении количества нитей вариант на atomic-op проигрывает гораздо больше варианту с mutex-ом, чем на однопроцессорной (разрыв больше).


E>У тебя есть возможность прогнать этот тест на 4-х процессорной машине? (А то в моем распоряжении только 2-х процессорные). Требуется ACE, я использовал ACE 5.5.6.

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 08.05.07 07:08
Оценка:
Здравствуйте, eao197, Вы писали:

E>>Я тут сваял тестик с некоторой имитацией подсчета ссылок в SObjectizer. Он делает подсчет ссылок на основе блокировке на mutex-е (фактически, critical section в Windows) и на основе atomic-операций. Дело в том, что в SObjectizer нужно увеличивать не один счетчик, а четыре. Поэтому интересно было сравнить, насколько четыре atomic-op выгоднее, чем один mutex. Оказались, что не выгоднее.


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


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.05.07 07:24
Оценка:
Здравствуйте, remark, Вы писали:

R>Ты тут немного смухлевал

R>У тебя там не 4 счётчика под одним мьютексом меняются, а два под одним, и потом ещё два под другим. Т.ч. я думаю, тут производительность должна быть практически одинаковой, что так 4 счётчика менять, что все 4 interlocked операциями. Даже должно быть под сильной нагрузкой interlocked чуть быстрее.

Ты имеешь в виду SObjectizer?
Так если interlocked не дают ощутимого преимущества, то не видно причин менять существующий и отлаженный код на новый, который еще предстоит написать и отладить. И при наличии вероятности, что для какой-нибудь платформы в ACE не будет эффективной реализации atomic-операций.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 08.05.07 09:21
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Ты тут немного смухлевал

R>>У тебя там не 4 счётчика под одним мьютексом меняются, а два под одним, и потом ещё два под другим. Т.ч. я думаю, тут производительность должна быть практически одинаковой, что так 4 счётчика менять, что все 4 interlocked операциями. Даже должно быть под сильной нагрузкой interlocked чуть быстрее.

E>Ты имеешь в виду SObjectizer?


Да. Методы agent_wrapper_base_t::inc_ref_count()/agent_wrapper_base_t::dec_ref_count()

E>Так если interlocked не дают ощутимого преимущества, то не видно причин менять существующий и отлаженный код на новый, который еще предстоит написать и отладить. И при наличии вероятности, что для какой-нибудь платформы в ACE не будет эффективной реализации atomic-операций.


Как говорится "моё дело предложить — твоё дело отказаться"
Ну вообще задача не просто заменить мьютексы на atomic-операции, задача — сделать 0 (прописью: ноль ) atomic-операций на основном пути отправки сообщений. Этот тест это ты написал, а не я


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[13]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.05.07 09:28
Оценка:
Здравствуйте, remark, Вы писали:

R>Да. Методы agent_wrapper_base_t::inc_ref_count()/agent_wrapper_base_t::dec_ref_count()


Ok.

E>>Так если interlocked не дают ощутимого преимущества, то не видно причин менять существующий и отлаженный код на новый, который еще предстоит написать и отладить. И при наличии вероятности, что для какой-нибудь платформы в ACE не будет эффективной реализации atomic-операций.


R>Как говорится "моё дело предложить — твоё дело отказаться"


Именно. Поэтому огромное спасибо за участие.
Будет возможность -- черкни мне письмецо с твоими координатами для включения в THANKS.

R>Ну вообще задача не просто заменить мьютексы на atomic-операции, задача — сделать 0 (прописью: ноль ) atomic-операций на основном пути отправки сообщений. Этот тест это ты написал, а не я


Я пока не вижу, как вообще отказаться от синхронизации. Кстати, подозреваю, что по сравнению с mutex-ами или atomic-операциями TLS так же будет не самым дешовым вариантом.

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

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

В любом случае


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[9]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 08.05.07 09:30
Оценка:
Здравствуйте, eao197, Вы писали:

E>Я тут сваял тестик с некоторой имитацией подсчета ссылок в SObjectizer. Он делает подсчет ссылок на основе блокировке на mutex-е (фактически, critical section в Windows) и на основе atomic-операций. Дело в том, что в SObjectizer нужно увеличивать не один счетчик, а четыре. Поэтому интересно было сравнить, насколько четыре atomic-op выгоднее, чем один mutex. Оказались, что не выгоднее.



Я тут такой провёл эксперимент.
Запустил бенчмарк customer_ring (ring size: 10000; token count: 100; dispatcher: one thread) — получил пропускную способность 162000.
Потом убрал в функции send_msg() rw_mutex so_4::rt::impl::kernel_t::shutdown_preventer_t shutdown_preventer
получил пропускную способность 163000
Потом убрал мьютексы в функциях agent_wrapper_base_t::inc_ref_count()/agent_wrapper_base_t::dec_ref_count() (те самые, которые считают референс каунтеры для сообщений/событий/агентов)
получил пропускную способность 167000

... прирост не то чтобы особо существенный... даже если убрать все эти мьютексы...
Вообще-то я же тестировал на одноядерном AMD (а AMD похоже грамотно обрабатывают атомарные операции в одноядерном режиме — не вносят никакого оверхеда)...

А ты не пробовал такой тест проводить — если убрать всю синхронизацию на основном пути?
Ну типа, что б вообще понять предел, к чему можно стремится. И что б понять, что узкое место именно здесь. Особенно было бо интересно поглядеть для двухядерной машины.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[14]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 08.05.07 09:42
Оценка:
Здравствуйте, eao197, Вы писали:

R>>Как говорится "моё дело предложить — твоё дело отказаться"


E>Именно. Поэтому огромное спасибо за участие.

E>Будет возможность -- черкни мне письмецо с твоими координатами для включения в THANKS.



R>>Ну вообще задача не просто заменить мьютексы на atomic-операции, задача — сделать 0 (прописью: ноль ) atomic-операций на основном пути отправки сообщений. Этот тест это ты написал, а не я


E>Я пока не вижу, как вообще отказаться от синхронизации. Кстати, подозреваю, что по сравнению с mutex-ами или atomic-операциями TLS так же будет не самым дешовым вариантом.


Если взять TLS как его предоставляет Win API, то это очень-очень быстро — это затрагивает не более чем пара машинных инструкций — косвенное обращение и инкремент — естественно, что никакой синхронизации и никаких обращений к глобальным данным.
Что поверх этого наворачивает pthread или ACE — это уже другой вопрос — но надо надеятся, что тоже не очень много.
TLS — это _очень_ мощный инструмент для оптимизации многопоточных приложений.


E>У меня сейчас есть какие-то смутные идеи по организации чего-то вроде сборки мусора для таких сущностей как msg_data_impl_t и event_data_impl_t. Т.е. при их создании инкрементируется счетчик ссылок у агента, но не в таком количестве раз, как сейчас. А затем они убиваются не сразу после своей обработки, а при неких подходящих условиях.


E>Возможно, количество обращений к мутексу получится серьезно сократить.


Вот это уже в правильном направлении мысли
Если будет время может попробую сделать патч к SObjectizer как я себе это вижу...


E>В любом случае


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.05.07 09:48
Оценка:
Здравствуйте, remark, Вы писали:

R>Я тут такой провёл эксперимент.

R>Запустил бенчмарк customer_ring (ring size: 10000; token count: 100; dispatcher: one thread) — получил пропускную способность 162000.
R>Потом убрал в функции send_msg() rw_mutex so_4::rt::impl::kernel_t::shutdown_preventer_t shutdown_preventer
R>получил пропускную способность 163000
R>Потом убрал мьютексы в функциях agent_wrapper_base_t::inc_ref_count()/agent_wrapper_base_t::dec_ref_count() (те самые, которые считают референс каунтеры для сообщений/событий/агентов)
R>получил пропускную способность 167000

R>... прирост не то чтобы особо существенный... даже если убрать все эти мьютексы...

R>Вообще-то я же тестировал на одноядерном AMD (а AMD похоже грамотно обрабатывают атомарные операции в одноядерном режиме — не вносят никакого оверхеда)...

R>А ты не пробовал такой тест проводить — если убрать всю синхронизацию на основном пути?

R>Ну типа, что б вообще понять предел, к чему можно стремится. И что б понять, что узкое место именно здесь. Особенно было бо интересно поглядеть для двухядерной машины.

Я пока возьму тайм-аут чтобы разобраться с текущими делами.
Когда готовил третью бету SObjectizer, то проводил какие-то такие эксперименты. Что именно я убирал не помню, но без использования мутексов прирост составлял что-то порядка +20K сообщений в секунду на моем Centrino 1.5GHz.

PS. Координаты твои получил. В следуюей версии SObjectizer будут в THANKS


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.05.07 14:33
Оценка:
Здравствуйте, remark, Вы писали:

R>Ты тут немного смухлевал

R>У тебя там не 4 счётчика под одним мьютексом меняются, а два под одним, и потом ещё два под другим. Т.ч. я думаю, тут производительность должна быть практически одинаковой, что так 4 счётчика менять, что все 4 interlocked операциями. Даже должно быть под сильной нагрузкой interlocked чуть быстрее.

Как оказалось, смухлевал не немного, а много
Вот версия, которая использует два мутекса (по два счетчика под каждым). А так же содержит тест TLS (в терминологии ACE -- TSS).

Под WinXP для параметров 10 (объектов), 4 нити на каждый объект, 1000000 итераций:
mutex:  10.463
atomic:  6.558
tss:     7.229

То же параметры под Linux (Slackware 10.2, ядро 2.6.13):
mutex:  19.382
atomic:  5.539
tss:     8.193

Имеет смысл заниматься Atomic-ом.

Под Windows с использованием ACE 5.5.8 очень быстро вылазят ограничение на количество TLS переменных в программе. Уже при 15 объектах и 4 нитях на объект вылазят ошибки при обращении к TLS-счетчикам (видимо, TlsAlloc для них завершается неудачно).


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 08.05.07 16:43
Оценка:
Здравствуйте, eao197, Вы писали:

E>Под WinXP для параметров 10 (объектов), 4 нити на каждый объект, 1000000 итераций:

E>
E>mutex:  10.463
E>atomic:  6.558
E>tss:     7.229
E>

E>То же параметры под Linux (Slackware 10.2, ядро 2.6.13):
E>
E>mutex:  19.382
E>atomic:  5.539
E>tss:     8.193
E>




E>Имеет смысл заниматься Atomic-ом.





E>Под Windows с использованием ACE 5.5.8 очень быстро вылазят ограничение на количество TLS переменных в программе. Уже при 15 объектах и 4 нитях на объект вылазят ошибки при обращении к TLS-счетчикам (видимо, TlsAlloc для них завершается неудачно).


Странно... это под Win98 было порядка 20 слотов, а начиная с Win2k там вроде должно быть порядка 1000...
В любом случае выделять слот на каждый пук не стоит, т.к. выделение может быть _очень_ медленным, к тому же всё равно слоты рано или поздно кончатся.
В таких ситуациях обычно выделяют один слот, например, на библиотеку или на какую-либо подсистему и далее хранят в этом слоте некое множество объектов. Правда тут встаёт вопрос о быстром поиске в этом множестве...
Странно вообще, что у тебя TLS получился такой медленный... А ты случаем в цикле не выделяешь слоты? Может это оверхед ACE... Он же как раз по ходу должен в одном слоте хранить что-то типа map...

Кстати, это ты на какой тачке мерил? На одноядерной или на двуядерной? Если на одноядерной, то на двуядерной должно быть ещё круче


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[13]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.05.07 16:57
Оценка:
Здравствуйте, remark, Вы писали:

E>>Под Windows с использованием ACE 5.5.8 очень быстро вылазят ограничение на количество TLS переменных в программе. Уже при 15 объектах и 4 нитях на объект вылазят ошибки при обращении к TLS-счетчикам (видимо, TlsAlloc для них завершается неудачно).


R>Странно... это под Win98 было порядка 20 слотов, а начиная с Win2k там вроде должно быть порядка 1000...

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

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

R>В таких ситуациях обычно выделяют один слот, например, на библиотеку или на какую-либо подсистему и далее хранят в этом слоте некое множество объектов. Правда тут встаёт вопрос о быстром поиске в этом множестве...


Вряд ли обычный std::map даст существенный оверхед по сравнению с mutex-ом

R>Кстати, это ты на какой тачке мерил? На одноядерной или на двуядерной? Если на одноядерной, то на двуядерной должно быть ещё круче


На одноядерной. Не всегда есть возможность на двухпроцессорной машине гонять тесты.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[15]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 08.05.07 21:37
Оценка: 21 (1)
Здравствуйте, remark, Вы писали:

R>Если будет время может попробую сделать патч к SObjectizer как я себе это вижу...


Я заинвестегировал процесс отправки/приёма сообщений с т.з. синхронизации в SObjectizer. Получается следующая картина:

Отправка сообщения:
shutdown_preventer: rw_mutex — при входе lock/unlock, при выходе lock/unlock (4)
kernel_t::read_access_t: аналогично (4)
создание msg_data_t: new + 3 * lock/unlock (8)
ещё раз kernel_t::read_access_t (4)
создание евента/рутинг/помещение в очередь: 2 * new + 7 * lock/unlock (на каждый евент) (18)

Получение и обработка евента:
3 * lock/unlock (6)

под lock/unlock я подразумеваю захват и освобождение обычного мьютекса (критической секции под win)
под new можно подразумевать тоже самое с т.з. синхронизации

Итого получается на одно сообщение: (20 + 24 * event_count) входов или выходов из мьютекса
если event_count == 1, то 44 interlocked операции

Часть мьютексов можно убрать даже без особых ухищрений.
Вначале отправки захватывается kernel_t::read_access_t, потом отпускается и сразу захватывается снова — можно его уж и не отпускать, тогда убирается 2 захвата и освобождения мьютекса. Правда вопрос — не начнутся ли дедлоки...

Вначале отправки захватывается shutdown_preventer и примерно с ним же захватывается kernel_t::read_access_t. Если их объединить в один, то убирается ещё 2 захвата и освобождения мьютекса.

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

Итого 12 из 44 элиминировали... осталось 32

При создании и рутинге евента тоже можно убрать лишние инкременты и декременты счётчиков — там 3 раза счётчики инкрементируются и потом сразу 2 раза декрементируются. Скорее всего это избыточные операции, т.е. должен быть только один инкремент. Т.о. убирается ещё 4 захвата и освобождения мьютекса.

Т.е. от 44 остаётся 24... по-моему уже лучше


E>>В любом случае

R>

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.05.07 06:43
Оценка:
Здравствуйте, remark, Вы писали:

R>Я тут такой провёл эксперимент.

R>Запустил бенчмарк customer_ring (ring size: 10000; token count: 100; dispatcher: one thread) — получил пропускную способность 162000.
R>Потом убрал в функции send_msg() rw_mutex so_4::rt::impl::kernel_t::shutdown_preventer_t shutdown_preventer
R>получил пропускную способность 163000
R>Потом убрал мьютексы в функциях agent_wrapper_base_t::inc_ref_count()/agent_wrapper_base_t::dec_ref_count() (те самые, которые считают референс каунтеры для сообщений/событий/агентов)
R>получил пропускную способность 167000

У меня, если закомментировать код методов class_handler_impl_t::start_ref_count_op() и class_handler_impl_t::finish_ref_count_op() получаются такие результаты:
тест customer_ring: 160000 против 142500
тест send_msg: 438000 против 392000


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[16]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.05.07 08:04
Оценка:
Здравствуйте, remark, Вы писали:

R>Я заинвестегировал процесс отправки/приёма сообщений с т.з. синхронизации в SObjectizer. Получается следующая картина:


Да, не слабую ты работу проделал! Внушаить


R>Отправка сообщения:

R>shutdown_preventer: rw_mutex — при входе lock/unlock, при выходе lock/unlock (4)
R>kernel_t::read_access_t: аналогично (4)
R>создание msg_data_t: new + 3 * lock/unlock (8)
R>ещё раз kernel_t::read_access_t (4)
R>создание евента/рутинг/помещение в очередь: 2 * new + 7 * lock/unlock (на каждый евент) (18)

R>Получение и обработка евента:

R>3 * lock/unlock (6)

R>под lock/unlock я подразумеваю захват и освобождение обычного мьютекса (критической секции под win)

R>под new можно подразумевать тоже самое с т.з. синхронизации

R>Итого получается на одно сообщение: (20 + 24 * event_count) входов или выходов из мьютекса

R>если event_count == 1, то 44 interlocked операции

R>Часть мьютексов можно убрать даже без особых ухищрений.

R>Вначале отправки захватывается kernel_t::read_access_t, потом отпускается и сразу захватывается снова — можно его уж и не отпускать, тогда убирается 2 захвата и освобождения мьютекса. Правда вопрос — не начнутся ли дедлоки...

R>Вначале отправки захватывается shutdown_preventer и примерно с ним же захватывается kernel_t::read_access_t. Если их объединить в один, то убирается ещё 2 захвата и освобождения мьютекса.


Нет, дедлоки не начнутся. Но два захвата kernel_t::read_access_t нужны для того, чтобы запускать checker-ов сообщений (если таковые есть) при незаблокированном ядре. Поскольку никаких ограничений на код checker-а нет (и вряд ли может быть), то checker может надолго заблокировать ядро, что не даст другим фрагментам программы работать с SObjectizer.

Однако, в течении все операции отсылки сообщения операция shutdown должна быть запрещена, поэтому shutdown_preventer должен быть независимым от kernel_t::read_access_t. Другое дело, что, возможно, shutdown_preventer можно через atomic-операции и condition variable реализовать. Может быть, будет дешевле.

R>При создании msg_data_t отрабатывает конструктор копирования и деструктор, которые лишний раз инкремекнтируют и декремекнтируют счётчики. Если создавать объект поместу — без конструктора копирования и лишнего деструктора, то опять же убирается 2 захвата и освобождения мьютекса.


R>При создании и рутинге евента тоже можно убрать лишние инкременты и декременты счётчиков — там 3 раза счётчики инкрементируются и потом сразу 2 раза декрементируются. Скорее всего это избыточные операции, т.е. должен быть только один инкремент. Т.о. убирается ещё 4 захвата и освобождения мьютекса.


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[17]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 09.05.07 10:55
Оценка:
Здравствуйте, eao197, Вы писали:

E>Да, не слабую ты работу проделал! Внушаить

E>

Продебажил просто


E>Нет, дедлоки не начнутся. Но два захвата kernel_t::read_access_t нужны для того, чтобы запускать checker-ов сообщений (если таковые есть) при незаблокированном ядре. Поскольку никаких ограничений на код checker-а нет (и вряд ли может быть), то checker может надолго заблокировать ядро, что не даст другим фрагментам программы работать с SObjectizer.


Можно вынести проверку сообщения вообще за критический регион.
Там же нужно только само пользовательское сообщение и функция проверки. Я видел, что функция проверки ищется через системный словарь, но ведь фактически она известна априори — можно как-то сделать, что бы её не надо было искать через словарь. Тогда можно сделать один rw_lock вместо трёх...

Кстати вот эта информация:


SOL4_CLASS_START( a_customer_t )
SOL4_MSG_START( msg_take_token, a_customer_t::msg_take_token )
SOL4_MSG_CHECKER( a_customer_t::msg_take_token::check )
SOL4_MSG_FINISH()

SOL4_EVENT( evt_start )
SOL4_EVENT_STC( evt_take_token, a_customer_t::msg_take_token )

SOL4_STATE_START( st_normal )
SOL4_STATE_EVENT( evt_start )
SOL4_STATE_EVENT( evt_take_token )
SOL4_STATE_FINISH()

SOL4_CLASS_FINISH()


Может меняться в ран-тайм. Или эти все данные генерируются при старте и потом при работе не меняются. Я имею в виду появление новых типов агентов, сообщений или событий, а так же их изменение и удаление.
Если не меняется, то всю эту информацию можно вынести в константный глобальный объект, для доступа к которому не надо мьютексов.


E>Однако, в течении все операции отсылки сообщения операция shutdown должна быть запрещена, поэтому shutdown_preventer должен быть независимым от kernel_t::read_access_t. Другое дело, что, возможно, shutdown_preventer можно через atomic-операции и condition variable реализовать. Может быть, будет дешевле.


Если сделать предыдущий пункт, то их можно объединить...


R>>При создании msg_data_t отрабатывает конструктор копирования и деструктор, которые лишний раз инкремекнтируют и декремекнтируют счётчики. Если создавать объект поместу — без конструктора копирования и лишнего деструктора, то опять же убирается 2 захвата и освобождения мьютекса.


R>>При создании и рутинге евента тоже можно убрать лишние инкременты и декременты счётчиков — там 3 раза счётчики инкрементируются и потом сразу 2 раза декрементируются. Скорее всего это избыточные операции, т.е. должен быть только один инкремент. Т.о. убирается ещё 4 захвата и освобождения мьютекса.


E>Да, инкременты в msg_data_t и event_data_t составляют сейчас самое узкое место. Если от них избавиться, то можно убрать существенный оверхед.


Там надо аккуратно переписать. что бы не делать лишних парных инкрементов/декрементов — я вроде таких 3 штуки насчитал при отправке...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[18]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.05.07 17:26
Оценка:
Здравствуйте, remark, Вы писали:

E>>Нет, дедлоки не начнутся. Но два захвата kernel_t::read_access_t нужны для того, чтобы запускать checker-ов сообщений (если таковые есть) при незаблокированном ядре. Поскольку никаких ограничений на код checker-а нет (и вряд ли может быть), то checker может надолго заблокировать ядро, что не даст другим фрагментам программы работать с SObjectizer.


R>Можно вынести проверку сообщения вообще за критический регион.

R>Там же нужно только само пользовательское сообщение и функция проверки. Я видел, что функция проверки ищется через системный словарь, но ведь фактически она известна априори — можно как-то сделать, что бы её не надо было искать через словарь. Тогда можно сделать один rw_lock вместо трёх...

Сейчас в SObjectizer нужно по имени сообщения найти его тип и уже там функцию checker. А для этого нужно обратиться в системный словарь.

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

R>Кстати вот эта информация:


R>

R>SOL4_CLASS_START( a_customer_t )
R> SOL4_MSG_START( msg_take_token, a_customer_t::msg_take_token )
R> SOL4_MSG_CHECKER( a_customer_t::msg_take_token::check )
R> SOL4_MSG_FINISH()

R> SOL4_EVENT( evt_start )
R> SOL4_EVENT_STC( evt_take_token, a_customer_t::msg_take_token )

R> SOL4_STATE_START( st_normal )
R> SOL4_STATE_EVENT( evt_start )
R> SOL4_STATE_EVENT( evt_take_token )
R> SOL4_STATE_FINISH()

R>SOL4_CLASS_FINISH()


R>Может меняться в ран-тайм. Или эти все данные генерируются при старте и потом при работе не меняются. Я имею в виду появление новых типов агентов, сообщений или событий, а так же их изменение и удаление.

R>Если не меняется, то всю эту информацию можно вынести в константный глобальный объект, для доступа к которому не надо мьютексов.

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

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

Так что идея иметь read-only словарь, который может всеми читаться без блокировок, мне очень симпатична. Если бы еще знать, как его реализовать.

E>>Да, инкременты в msg_data_t и event_data_t составляют сейчас самое узкое место. Если от них избавиться, то можно убрать существенный оверхед.


R>Там надо аккуратно переписать. что бы не делать лишних парных инкрементов/декрементов — я вроде таких 3 штуки насчитал при отправке...


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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 10.05.07 16:21
Оценка:
Здравствуйте, eao197, Вы писали:

E>Как оказалось, смухлевал не немного, а много

E>Вот версия, которая использует два мутекса (по два счетчика под каждым). А так же содержит тест TLS (в терминологии ACE -- TSS).

Попробуй так, что бы увидеть tss raw performance

#include <windows.h>

class object_with_refcount_t
{
public :
virtual ~object_with_refcount_t();

virtual void
init_in_thread() {}; // <-------------------------

virtual void
inc_ref_count() = 0;

virtual void
dec_ref_count() = 0;
};

// Реализация подсчета ссылок на основе TSS.
class refcount_by_tss_t
: public object_with_refcount_t
{
public :
refcount_by_tss_t();

virtual void
init_in_thread(); // <-------------------------

virtual void
inc_ref_count();

virtual void
dec_ref_count();

private :
struct inner
{
unsigned long m_c1;
unsigned long m_c2;
unsigned long m_c3;
unsigned long m_c4;
};

static DWORD tls_slot;
};

DWORD refcount_by_tss_t::tls_slot = 0;

refcount_by_tss_t::refcount_by_tss_t()
{
if (!tls_slot) tls_slot = TlsAlloc();
}

void
refcount_by_tss_t::init_in_thread()
{
TlsSetValue(tls_slot, new inner);
}

void
refcount_by_tss_t::inc_ref_count()
{
inner& i = *(inner*)TlsGetValue(tls_slot);
++i.m_c1;
++i.m_c2;
++i.m_c3;
++i.m_c4;
}

void
refcount_by_tss_t::dec_ref_count()
{
inner& i = *(inner*)TlsGetValue(tls_slot);
--i.m_c1;
--i.m_c2;
--i.m_c3;
--i.m_c4;
}

ACE_THR_FUNC_RETURN
work_thread( void * param )
{
bench_data_t * bench =
reinterpret_cast< bench_data_t * >( param );

bench->init_in_thread(); // <-------------------------

for( unsigned int i = 0; i != bench->m_cycles; )
{
bench->m_object->inc_ref_count();
++i;
bench->m_object->dec_ref_count();
}

return 0;
}



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[13]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.05.07 16:28
Оценка:
Здравствуйте, remark

Появится время, попробую.

Дима, я не знаю, читает ли эту тему кто-нибудь, кроме нас. Может переместим такие технические обсуждения на SourceForge? Вот сюда: http://sourceforge.net/forum/forum.php?forum_id=550088



SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 10.05.07 16:42
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark


E>Появится время, попробую.


E>Дима, я не знаю, читает ли эту тему кто-нибудь, кроме нас. Может переместим такие технические обсуждения на SourceForge? Вот сюда: http://sourceforge.net/forum/forum.php?forum_id=550088


Перешёл.
Единственная засада — там не работает

E>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[15]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 10.05.07 16:52
Оценка:
Здравствуйте, remark, Вы писали:

R>Единственная засада — там не работает


Ну столько beer-а я уже выпить не могу
Там еще цитировать не получается, вот это хуже


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.05.07 06:58
Оценка:
Здравствуйте, eao197, Вы писали:

R>>Запустил бенчмарк customer_ring (ring size: 10000; token count: 100; dispatcher: one thread) — получил пропускную способность 162000.

R>>Потом убрал в функции send_msg() rw_mutex so_4::rt::impl::kernel_t::shutdown_preventer_t shutdown_preventer
R>>получил пропускную способность 163000
R>>Потом убрал мьютексы в функциях agent_wrapper_base_t::inc_ref_count()/agent_wrapper_base_t::dec_ref_count() (те самые, которые считают референс каунтеры для сообщений/событий/агентов)
R>>получил пропускную способность 167000

E>У меня, если закомментировать код методов class_handler_impl_t::start_ref_count_op() и class_handler_impl_t::finish_ref_count_op() получаются такие результаты:

E>тест customer_ring: 160000 против 142500
E>тест send_msg: 438000 против 392000

Немного покурил над msg_data_t. Обнаружил, что от одной операции инкремента/декремента вполне можно избавиться. Избавился и теперь получается:
тест customer_ring: 154000 против 142500;
тест send_msg: 435000 против 392000.

Кстати, я отладочными печатями и отладочными счетчиками подсчитал, что на каждое сообщение+событие (в тестах customer_ring и send_and_process_msg) выполняется 8 операций инкремента/декремента количества ссылок.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 11.05.07 11:24
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, eao197, Вы писали:


R>>>Запустил бенчмарк customer_ring (ring size: 10000; token count: 100; dispatcher: one thread) — получил пропускную способность 162000.

R>>>Потом убрал в функции send_msg() rw_mutex so_4::rt::impl::kernel_t::shutdown_preventer_t shutdown_preventer
R>>>получил пропускную способность 163000
R>>>Потом убрал мьютексы в функциях agent_wrapper_base_t::inc_ref_count()/agent_wrapper_base_t::dec_ref_count() (те самые, которые считают референс каунтеры для сообщений/событий/агентов)
R>>>получил пропускную способность 167000

E>>У меня, если закомментировать код методов class_handler_impl_t::start_ref_count_op() и class_handler_impl_t::finish_ref_count_op() получаются такие результаты:

E>>тест customer_ring: 160000 против 142500
E>>тест send_msg: 438000 против 392000

E>Немного покурил над msg_data_t. Обнаружил, что от одной операции инкремента/декремента вполне можно избавиться. Избавился и теперь получается:


Ты случаем исправил не тоже, что я уже у себя исправил:
в функции send_msg() создание сообщения я исправил, т.ч тут не отрабатывает конструктор копирования и исчезает одна лишняя пара икремент/декремент:

to_deliver.reset( // <-------------------
new so_4::rt::impl::msg_data_impl_t(
msg_data, msg_wrapper, receiver,
channel_to,
// В качестве отправителя — localhost
so_4::rt::comm_channel_t::localhost(),
true), // <-------------------
false); // <-------------------

Я тут сразу создаю msg_data_impl_t со счётчиком = 1 и инкрементирую счётчик агента атомарной операцией


E>тест customer_ring: 154000 против 142500;

E>тест send_msg: 435000 против 392000.

Чо-то я не понял, что ты убрал — стало ж только медленнее


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[13]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.05.07 12:01
Оценка:
Здравствуйте, remark, Вы писали:

R>Ты случаем исправил не тоже, что я уже у себя исправил:


Именно то
Этот фрагмент используется не только в send_msg, но и при обработке входящего SOP-пакета send_msg.
Но я сделал в msg_data_t оператор копирования, который получает msg_data_impl_t *.
Пока без атомарных операций.

E>>тест customer_ring: 154000 против 142500;

E>>тест send_msg: 435000 против 392000.

R>Чо-то я не понял, что ты убрал — стало ж только медленнее


Ну как же медленее
Большие числа -- это показатели новой версии.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 11.05.07 14:31
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Ты случаем исправил не тоже, что я уже у себя исправил:


E>Именно то

E>Этот фрагмент используется не только в send_msg, но и при обработке входящего SOP-пакета send_msg.
E>Но я сделал в msg_data_t оператор копирования, который получает msg_data_impl_t *.
E>Пока без атомарных операций.



А я сделал функцию reset(), что б лишний раз не копировать...
И я сделал у конструктора msg_data_t доп. параметр, что б сразу устанавливать счётчик в 1...

E>>>тест customer_ring: 154000 против 142500;

E>>>тест send_msg: 435000 против 392000.

R>>Чо-то я не понял, что ты убрал — стало ж только медленнее


E>Ну как же медленее

E>Большие числа -- это показатели новой версии.


E>У меня, если закомментировать код методов class_handler_impl_t::start_ref_count_op() и class_handler_impl_t::finish_ref_count_op() получаются такие результаты:
E>тест customer_ring: 160000 против 142500
E>тест send_msg: 438000 против 392000

Немного покурил над msg_data_t. Обнаружил, что от одной операции инкремента/декремента вполне можно избавиться. Избавился и теперь получается:
тест customer_ring: 154000 против 142500;
тест send_msg: 435000 против 392000.


Первые числа не изменились, а вторые не изменились... ... либо мне спать надо больше?

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[15]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 11.05.07 14:45
Оценка:
Здравствуйте, remark, Вы писали:

E>>Большие числа -- это показатели новой версии.


R>

E>>У меня, если закомментировать код методов class_handler_impl_t::start_ref_count_op() и class_handler_impl_t::finish_ref_count_op() получаются такие результаты:
E>>тест customer_ring: 160000 против 142500
E>>тест send_msg: 438000 против 392000

R>Немного покурил над msg_data_t. Обнаружил, что от одной операции инкремента/декремента вполне можно избавиться. Избавился и теперь получается:
R>тест customer_ring: 154000 против 142500;
R>тест send_msg: 435000 против 392000.


R>Первые числа не изменились, а вторые не изменились... ... либо мне спать надо больше?


Если брать тест customer_ring, то значение 142500 -- это показатель версии 4.4.b3 (последней официальной беты). Значение 160000 получается, если в class_handler_impl_t закомментировать операции с мутексами, т.е. когда блокировок вообще нет. А значение 154000 получается в текущей версии после удаления одной лишней блокировки.

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


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 12.05.07 07:03
Оценка:
Здравствуйте, remark, Вы писали:

R>>>Хм... а почему нельзя использовать Interlocked-операции?


E>>Потому что изменение счетчика ссылок на сообщение должно выполняться в одной же транзакции с изменением счетчика ссылок на агента-владельца. А иногда и еще какой-то счетчик задействуется (если не забыл ничего). Т.е. за раз нужно изменять сразу несколько ссылок.


R>А почему это должно быть именно в одной транзакции? Почему никто не должен видеть эти счётчики в рассогласованных состояниях? Ведь с reference counting'ом обычно так — или в счётчике не ноль и тогда собственно пофигу что, т.к. объект не удаляется, или в счётчике 0, и тогда вобщем-то тоже пофигу, т.к. объект удаляется...


Дима, спасибо за эту подсказку!

Я сделал счетчики ссылок на основе ACE_Atomic_Op. Причем вот с такой оптимизацией: счетчик ссылок на агента изменяется только два раза:
1) при первом инкременте ссылки на msg_data_impl_t/event_data_impl_t (т.е. когда эти объекты только были созданы);
2) при последнем декременте ссылки на msg_data_impl_t/event_data_impl_t (т.е. когда эти объекты будут уничтожены).

Все остальные инкременты/декременты msg_data_impl_t/event_data_impl_t уже не оказываеют влияния на счетчик ссылок агента.

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

Если же ACE для какой-то платформы не предоставляет эффективной реализации ACE_Atomic_Op, то используется старая схема с мутексом.

На моем нуотбуке в тесте customer_ring прирост составил порядка 14K msg/sec по сравнении с версией 4.4.b3 (т.е. где-то 160K-158K в текущей версии против 142K-146K в v.4.4.b3). На тесте send_and_process_msg производительность send_msg увеличилась где-то на 10K msg/sec (266K в текущей версии против 255K в v.4.4.b3), а обработка событий вообще на 40K evt/sec (492K в текущей версии против 456K в v.4.4.b3).




Я вот что думаю -- может эксперименты по выжиманию скорости из send_msg() пока прекратить. Для версии 4.4.b4 есть еще одна очень важная задача -- изменения способа работы с транспортными каналами, т.к. текущая схема очень проста и неэффективна. Я думаю сосредоточится сейчас именно на транспортном слое. Это и будет версия 4.4.b4. Если же за это время появятся хорошие, не сложные и жизнеспособные идеи по дальнейшей оптимизации send_msg(), то их можно будет попробовать воплотить в 4.4.b5.

Ты как думаешь? (Может еще кто-нибудь из читателей форума выскажется?)


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[16]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 12.05.07 10:52
Оценка:
Здравствуйте, eao197, Вы писали:

E>Если брать тест customer_ring, то значение 142500 -- это показатель версии 4.4.b3 (последней официальной беты). Значение 160000 получается, если в class_handler_impl_t закомментировать операции с мутексами, т.е. когда блокировок вообще нет. А значение 154000 получается в текущей версии после удаления одной лишней блокировки.


Всё понял.

E>Вообще, замеры сильно отличаются в зависимости от того, сколько времени работала WinXP без перезагрузки. Если сразу после старта WinXP, то получается высокая скорость. После трех-четырех часов работы скорость заметно снижается. Так что к замерам нужно относиться с некоторой степенью недоверия.


Я у себя мерил на одноядерном P4 — у меня примерно такая же картина получилась — стабильно пропускная способность увеличилась на 6-7%. Т.ч. Я думаю, что так оно примерно и есть.
Вот ведь, а кажется убрал всего ничего...



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[9]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 12.05.07 12:16
Оценка:
Здравствуйте, eao197, Вы писали:

E>Дима, спасибо за эту подсказку!


E>Я сделал счетчики ссылок на основе ACE_Atomic_Op. Причем вот с такой оптимизацией: счетчик ссылок на агента изменяется только два раза:

E>1) при первом инкременте ссылки на msg_data_impl_t/event_data_impl_t (т.е. когда эти объекты только были созданы);
E>2) при последнем декременте ссылки на msg_data_impl_t/event_data_impl_t (т.е. когда эти объекты будут уничтожены).

E>Все остальные инкременты/декременты msg_data_impl_t/event_data_impl_t уже не оказываеют влияния на счетчик ссылок агента.


Я как раз примерно такую схему хотел предложить...

E>Такая оптимизация должна особенно сильно сказаться в случаях, когда msg_data_impl_t тиражируется (большое количество подписчиков на сообщение или сообщение является отложенным/периодическим).


E>Если же ACE для какой-то платформы не предоставляет эффективной реализации ACE_Atomic_Op, то используется старая схема с мутексом.


Да, мне кажется, что на всех она должна быть. Там разьве есть какие-то где нет?


E>


E>Я вот что думаю -- может эксперименты по выжиманию скорости из send_msg() пока прекратить. Для версии 4.4.b4 есть еще одна очень важная задача -- изменения способа работы с транспортными каналами, т.к. текущая схема очень проста и неэффективна. Я думаю сосредоточится сейчас именно на транспортном слое. Это и будет версия 4.4.b4. Если же за это время появятся хорошие, не сложные и жизнеспособные идеи по дальнейшей оптимизации send_msg(), то их можно будет попробовать воплотить в 4.4.b5.

E>Ты как думаешь? (Может еще кто-нибудь из читателей форума выскажется?)

Я ещё хотел такой вопрос поднять. А зачем вообще для евентов нужен подсчёт ссылок? Нельзя просто так — при диспетчеризации создали евенты, после обработки просто вызвали delete. Ну на агента всё равно в конструкторе инкрементируем, в деструкторе декрементируем.
Или для этого есть какие-то препядствия, когда более сложные схемы обрабоки?

Или вообще можно под евенты динамически память не выделять — там 16 байт — просто по значению и передавать и в очередь по значению и класть... Но на агента всё равно при этом придётся делать инкремент/декремент.


Из простых оптимизаций, которые не влияют на структуру системы, ещё могу обратить внимание на функцию:

inline void
send_event_to_dispatcher(
    dispatcher_t & disp,
    int priority,
    event_data_impl_t * evt_to_disp )
    {
        // Выставляем заявку диспетчеру.
        event_data_t object_of_event( evt_to_disp );

        disp.dispatch( priority, object_of_event );
    }
}


Тут для евента делается инкремент и декремент — и потом при непосредственно кладении в очередь demand_queue_t::push() ещё раз делается инкремент:

// Для защиты от исключений в момент помещения
// объекта в очередь.
std::auto_ptr< so_4::rt::event_data_t > event_data_guard(
    new so_4::rt::event_data_t( event ) );


Можно их совместить в один — т.е. сразу в функции send_event_to_dispatcher() создавать объект динамически, класть в std::auto_ptr и потом делать release().


И ещё — для всех объектов в конструкторе устанавливается счётчик в 0, потом явно инкрементируется. Было бы более целесообразно устанавливать в конструкторе счётчик в 1, тогда один инкремент убирается.
И даже больше — пока идёт диспетчиризация, т.е. внутри функции send_msg(), счётчик для msg_data_impl_t можно менять не атомарной операцией, а обычным "бесплатным" инкрементом. Т.е. допустим на сообщение создаётся 10 евентов — у сообщения просто ставим счётчик в 10. А потом, когда евенты рушатся, уже декрементируем счётчик сообщения атомарно. Т.о. тоже можно несколько лишних инкрементов убрать. Особенно, если евентов на сообщение создаётся много.


И ещё есть такой трюк малоизвестный, но прикольный. Он ещё один декремент уберёт.
Допустим у тебя есть код:
if (0 == atomic_dec(obj->ref_count))
  delete obj;


Его можно заменить на равноценный:
if (1 == obj->ref_count)
  delete obj;
else if (0 == atomic_dec())
  delete obj;


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


Т.о. если это всё воплотить, то получается следующее. Допустим на сообщение создаётся один евент. Инкрементируем счётчик агента сообщения, создаём сообщение сразу со счётчиком 1, создаём евент, инкрементируем счётчик агента евента. Кладём евент в очередь. Евент обрабатывается и удаляется. Декрементируется счётчик агента евента. Декрементируется счётчик сообщения без атомарных операций. Декрементируется счётчик агента сообщения.
Т.е. из атомарных операций всего 1 инкремент/декремент агента сообщения и 1 инкремент/декремент агента евента.


И ещё было бы круто разобраться с системным словарём. Т.к. при отправке сейчас 3 входа в rw_mutex (12 атомарных операций), а можно заменить на 1 вход в rw_mutex (4 атомарных операции). А если сделать крутой rw_mutex с lock-free быстрым путём, то останется только 2 атомарных операции.


Теоретически ещё можно оптимизировать demand_queue_t, т.к. там сейчас при добавлении евента 4 атомарных операции и туда все отправки упираются, т.е. там конкуренция сильная.
А вот кстати, что там можно сейчас сделать быстро — вынести создание евента из под мьютекса:
std::auto_ptr< so_4::rt::event_data_t > event_data_guard(
new so_4::rt::event_data_t( event ) );
Т.к. это увеличивает время нахождения под мьютексом.




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


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[10]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 13.05.07 08:14
Оценка:
Здравствуйте, remark, Вы писали:

E>>Если же ACE для какой-то платформы не предоставляет эффективной реализации ACE_Atomic_Op, то используется старая схема с мутексом.


R>Да, мне кажется, что на всех она должна быть. Там разьве есть какие-то где нет?


Если заглянуть в Atomic_Op.h, то там можно увидеть, что ACE_HAS_BUILTIN_ATOMIC_OP определяется для совсем небольшого количества платформ.

Например, нам приходилось работать на такой платформе, как HP NonStop. Ее в Atomic_Op.h нет, но поскольку сама платформа из-за собственных особенностей не сильно быстрая, то не хочется на ней терять производительность из-за того, что ACE_Atomic_Op будет работать через Mutex.

R>Я ещё хотел такой вопрос поднять. А зачем вообще для евентов нужен подсчёт ссылок? Нельзя просто так — при диспетчеризации создали евенты, после обработки просто вызвали delete. Ну на агента всё равно в конструкторе инкрементируем, в деструкторе декрементируем.

R>Или для этого есть какие-то препядствия, когда более сложные схемы обрабоки?

R>Или вообще можно под евенты динамически память не выделять — там 16 байт — просто по значению и передавать и в очередь по значению и класть... Но на агента всё равно при этом придётся делать инкремент/декремент.


Вообще-то идея была в том, чтобы предоставить пользователям самим определять собственные диспетчеры под собственные нужды без знания деталей реализации SObjectizer-а. Как в этих диспетчерах будет использоваться event_data_t сложно предположить -- он может либо быть сразу использован при вызове dispatcher_t::dispatch(), либо же пройдет долгий путь по внутренним структурам прежде чем попадет на обработку (как в случае с диспетчером для GUI библиотек, таких как Qt). Для облегчения жизни писателей диспетчера и была сделана схема, в которой event_data_t является аналогом shared_ptr с подсчетом ссылок для event_data_impl_t (и производных от event_data_impl_t сущностей). С ее помощью у разработчиков диспетчеров может быть больше свободы -- например, не задумываясь о последствиях можно помещать event_data_t в различные типы стандартных контейнеров.

Вот от выделения памяти под event_data_t, вероятно, стоит отказаться. Спасибо!

R>И ещё — для всех объектов в конструкторе устанавливается счётчик в 0, потом явно инкрементируется. Было бы более целесообразно устанавливать в конструкторе счётчик в 1, тогда один инкремент убирается.

R>И даже больше — пока идёт диспетчиризация, т.е. внутри функции send_msg(), счётчик для msg_data_impl_t можно менять не атомарной операцией, а обычным "бесплатным" инкрементом. Т.е. допустим на сообщение создаётся 10 евентов — у сообщения просто ставим счётчик в 10. А потом, когда евенты рушатся, уже декрементируем счётчик сообщения атомарно. Т.о. тоже можно несколько лишних инкрементов убрать. Особенно, если евентов на сообщение создаётся много.

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

R>И ещё есть такой трюк малоизвестный, но прикольный. Он ещё один декремент уберёт.

R>Допустим у тебя есть код:
R>
R>if (0 == atomic_dec(obj->ref_count))
R>  delete obj;
R>


R>Его можно заменить на равноценный:

R>
R>if (1 == obj->ref_count)
R>  delete obj;
R>else if (0 == atomic_dec())
R>  delete obj;
R>


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

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

Как-то пока мне это кажется подозрительным. Я покурю эту тему еще.
За остальные твои предложения отдельное спасибо! Мне нужно обдумать их в спокойной обстановке.

R>Моё видение такое. Я бы сделал примерно там, если бы сейчас делал с нуля. Ну ты сам смотри. Я так чувствую, что становлюсь немного навязчивым


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

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

R>




SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 13.05.07 13:35
Оценка:
Здравствуйте, eao197, Вы писали:

E>>>Если же ACE для какой-то платформы не предоставляет эффективной реализации ACE_Atomic_Op, то используется старая схема с мутексом.


R>>Да, мне кажется, что на всех она должна быть. Там разьве есть какие-то где нет?


E>Если заглянуть в Atomic_Op.h, то там можно увидеть, что ACE_HAS_BUILTIN_ATOMIC_OP определяется для совсем небольшого количества платформ.


Ну это видимо только из-за лени Шмидта

E>Например, нам приходилось работать на такой платформе, как HP NonStop. Ее в Atomic_Op.h нет, но поскольку сама платформа из-за собственных особенностей не сильно быстрая, то не хочется на ней терять производительность из-за того, что ACE_Atomic_Op будет работать через Mutex.


NonStop Kernel работал на MIPS — там есть инструкции LL/SC, что является аналогом CAS, а с MIPS II там даже есть LLD/SCD для атомарной работы с двойными словами. А сейчас NonStop делают на Itanium — там с этим точно всё в порядке — набор команд похож на x86.

Ну другое дело, конечно, что если в ACE нет, то придётся это руками докручивать... но для поддержки такой экзотической платформы как NonStop, наверное можно немного и докрутить...


R>>

E>

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 13.05.07 13:41
Оценка:
Здравствуйте, eao197, Вы писали:

R>>И ещё — для всех объектов в конструкторе устанавливается счётчик в 0, потом явно инкрементируется. Было бы более целесообразно устанавливать в конструкторе счётчик в 1, тогда один инкремент убирается.

R>>И даже больше — пока идёт диспетчиризация, т.е. внутри функции send_msg(), счётчик для msg_data_impl_t можно менять не атомарной операцией, а обычным "бесплатным" инкрементом. Т.е. допустим на сообщение создаётся 10 евентов — у сообщения просто ставим счётчик в 10. А потом, когда евенты рушатся, уже декрементируем счётчик сообщения атомарно. Т.о. тоже можно несколько лишних инкрементов убрать. Особенно, если евентов на сообщение создаётся много.

E>Не совсем так. В send_msg() есть момент, когда при разблокированном ядре msg_data_t отдается таймерной нити. Таймерная нить работает в параллель и может манипулировать msg_data_t в тоже самое время, пока send_msg() вызывает deliver_msg_on_nonblocked_kernel.


Я подозревал, что что-то такое есть
Ну может можно вначале отдеспетчеризировать в send_msg(), а потом уже отдавать в поток таймера... ну или ещё как-то так...


R>>

E>

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: SObjectizer: I Love This Game!
От: remark Россия http://www.1024cores.net/
Дата: 13.05.07 13:50
Оценка: 44 (1)
Здравствуйте, eao197, Вы писали:

R>>И ещё есть такой трюк малоизвестный, но прикольный. Он ещё один декремент уберёт.

R>>Допустим у тебя есть код:
R>>
R>>if (0 == atomic_dec(obj->ref_count))
R>>  delete obj;
R>>


R>>Его можно заменить на равноценный:

R>>
R>>if (1 == obj->ref_count)
R>>  delete obj;
R>>else if (0 == atomic_dec())
R>>  delete obj;
R>>


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

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

E>Как-то пока мне это кажется подозрительным. Я покурю эту тему еще.


Смотри
здесь по поводу этого трюка. Эксперты сошлись на том, что это безопасно для нормальной модели потоко-безопастности (это когда ты можешь увеличивать reference counter, только когда ты владеешь объектом, т.е. уже до этого один раз увеличивал reference counter), как раз то, что в SObjectizer.


R>>

E>

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: SObjectizer: I Love This Game!
От: Tom Россия http://www.RSDN.ru
Дата: 18.05.09 17:43
Оценка:
E>Если найдешь что-нибудь плохое, поделись впечатлениями, плз. Попробуем исправить.
110 тысяч строк кода — вот это основной недостаток.
Их должно быть 5-10 максимум и то много.
В серьёзном продукте такую огроменную библиотеку использовать я бы побоялся.
Народная мудрось
всем все никому ничего(с).
Re[4]: SObjectizer: I Love This Game!
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.05.09 18:41
Оценка:
Здравствуйте, Tom, Вы писали:

E>>Если найдешь что-нибудь плохое, поделись впечатлениями, плз. Попробуем исправить.

Tom>110 тысяч строк кода — вот это основной недостаток.
Tom>Их должно быть 5-10 максимум и то много.
Tom>В серьёзном продукте такую огроменную библиотеку использовать я бы побоялся.

В Crypto++ 60K строк. В POCO ~200K. В ACE больше 630K. В Boost 1.36.0 ~1730K (если выцепить оттуда только boost::unordered, то получится уже ~190K). Так что даже не знаю, не такие уж мы большие.

Надеюсь, что SObjectizer-5 будет построен по модульному принципу. И размер основного ядра серьезно уменьшится. Может быть, до 10-15K строк. А остальная функциональность (вроде транспортной подсистемы) может быть подключена по необходимости.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.