View this page "Есть ли альтернатива владению сообщениями?"

O afișare
Accesați primul mesaj necitit

eao197

necitită,
17 feb. 2009, 05:30:5417.02.2009
– SObjectizer
Имеет ли смысл отказаться от понятия владения сообщениями в
SObjectizer-5? И если "да", то в пользу чего?

Click on
http://groups.google.com/group/sobjectizer/web/%D0%B5%D1%81%D1%82%D1%8C+%D0%BB%D0%B8+%D0%B0%D0%BB%D1%8C%D1%82%D0%B5%D1%80%D0%BD%D0%B0%D1%82%D0%B8%D0%B2%D0%B0+%D0%B2%D0%BB%D0%B0%D0%B4%D0%B5%D0%BD%D0%B8%D1%8E+%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8%3F
- or copy & paste it into your browser's address bar if that doesn't
work.

Yauheni Akhotnikau

necitită,
17 feb. 2009, 06:17:1317.02.2009
– sobje...@googlegroups.com
On Tue, 17 Feb 2009 13:30:54 +0300, eao197 <eao...@intervale.ru> wrote:

>
> Имеет ли смысл отказаться от понятия владения сообщениями в
> SObjectizer-5? И если "да", то в пользу чего?
>

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

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

const so5::message_t< msg_client_connected > msg_client_connected_instance;

Для того, чтобы подписать событие на это сообщение используется
конструкция вида:

so_subscribe(
my_agent_t::evt_client_connected,
msg_client_connected_instance, ... );

Т.е. для того, чтобы подписаться на сообщение, должен быть доступен
экземпляр объекта so5::message_t.

Отсылка сообщения выполняется через этот же экземпляр:

msg_client_connected_instance.send( ... );

Таким образом, будет гарантироваться, что нельзя ни подписаться на
сообщение, которого нет, ни отослать его. Ведь для этих действий требуется
наличие C++ объекта.

Объект so5::message_t должен иметь тривиальную структуру, которая бы
позволила без проблем использовать объекты этого типа в качестве
глобальных переменных/констант или в качестве статических членов классов.

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

const so5::message_t< msg_client_connected > msg_client_connected_instance(
"msg_client_connected" );

В таком случае сообщение можно будет отослать в приложение через SOP.

Так же, для поддержки SOP нужно будет как-то управлять
сериализацией/десериализацией сообщения. Это так же можно делать с помощью
все того же экземпляра so5::message_t. Например, передавать тип
сериализатора/десериализатора в качестве шаблонного параметра:

const so5::message_t<
msg_client_connected,
objessty_serializer_t >
msg_client_connected_instance( "msg_client_connected" );

Или в качестве параметров конструктора so5::message_t:

const so5::message_t< msg_client_connected > msg_client_connected_instance(
"msg_client_connected",
msg_client_connected::serialize,
msg_client_connected::deserialize );

где serialize/deserialize -- это функции сериализации/десериализации.

--
Regards,
Yauheni Akhotnikau
Chief Developer
Intervale, http://www.intervale.ru
e-mail:eao...@intervale.ru <mailto:eao...@intervale.ru>

Dmitriy V'jukov

necitită,
17 feb. 2009, 14:11:3017.02.2009
– SObjectizer
Я честно говоря так никогда и непонимал смысл владения, поэтому
вначале хотел бы прояснить пару моментов. Я увидел 2 момента, для
которых применяется владение: (1) определение момента, когда можно
выгружать DLL плагин, (2) сужение множества получателей при
широковещательной рассылке. По поводу второго момента у меня некоторая
неясность. Во-первых, как я понял под термином "агент" ты имеешь в
виду то *класс* агента, то *инстанс* агента. Кто владеет сообщением -
класс или инстанс? При посылке сообщения мы к имени приписываем имя
класса или инстанса? Как я понял - при отсылке мы приписываем имя
инстанса агента, и т.о. сужаем множество получателей. Правильно?
Если выразить моё отношение в целом - то за отказ от владения, т.к.
как мне сейчас видится - это достаточно сомнительная синтетическая
абстракция.
По поводу использования (1). При подключении плагина, он всё равно
должен как-то "транспортировать" свою мета-информацию (о типах
агентов, сообщений и т.д.) внутрь приложения; плюс, если он сам
содержит статически влинкованный ран-тайм, то он должен переключить
его на использование ран-тайма из приложения. Соотв. в этот момент
можно и получить всю информацию о связи агентов и сообщений с
конкретной DLL, т.е. если тип сообщения был экспортирован из DLL, то
мы её не выгружаем, пока есть эти сообщения.
По поводу использования (2). Помнишь, я как-то тебя спрашивал
используется ли в SO приложенииях динамеческая генерация типов
сообщений, т.е. что-то типа "session/123/request"? Спрашивал я как раз
с мыслью о сужении списка получателей при широковешательной рассылке.
Насколько я помню, ты ответил, что нет, не используется. Но как я
сейчас вижу, она всё-таки используется - динамической частью типа
сообщения выступает имя владеющего агента. Правильно?
Я в этом отношении пока пришёл к мысли о явном создании "доменов"
обмена сообщеними. Всегда есть глобальный домен, так же можно
создавать произвольное кол-во дополнительных доменов. Соотв. при
подписке/отсылке сообщений указывается домен в котором идёт подписка/в
который отправлять сообщение. Если домен не указывается, то
используется глобальный. Домен хранит всю информацию о подписках -
какой агент на сообщения какого типа подписан. Домен может быть
глобальным, если определяет своё имя.
Схематический пример:

// допустим на сервер поступает новая сессия, тогда создаём домен под
неё:
so::domain d = so::domain::create("domain_for_session_123");

// далее уведомляем всех заинтересованных о новой сессии
// в сообщении передаём домен
so::send(msg_new_session::create(id, d));

// при получении этого сообщения заинтересованные агенты могут
подписаться на сообщения сессии в рамках этого домена
subscribe<msg_request>(d);

// отправка последующих сообщений для сессии производится в этом
домене
so::send(d, msg_request::create(...));

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

Dmitriy V'jukov

necitită,
17 feb. 2009, 14:16:4217.02.2009
– SObjectizer
On 17 фев, 14:17, "Yauheni Akhotnikau" <eao...@intervale.ru> wrote:
>
> const so5::message_t< msg_client_connected > msg_client_connected_instance;
>
> Для того, чтобы подписать событие на это сообщение используется  
> конструкция вида:
>
> so_subscribe(
>         my_agent_t::evt_client_connected,
>         msg_client_connected_instance, ... );
>

А зачем разделять само сообщение и so5::message_t?
В своём прототипе я это делал так:

struct my_msg : lib::msg<my_msg>
{
int data;
};

Поскольку тут присутствует шаблон lib::msg<my_msg>, то он может и
выделить уникальный id для типа, и зарегистрировать его, и т.д.
Необходимость в какой-либо проверке при отсылке отпадает, если
передаётся lib::msg_base*, то это - однозначно сообщение.

Yauheni Akhotnikau

necitită,
17 feb. 2009, 15:02:0117.02.2009
– sobje...@googlegroups.com
On Tue, 17 Feb 2009 22:16:42 +0300, Dmitriy V'jukov <dvy...@gmail.com>
wrote:

> А зачем разделять само сообщение и so5::message_t?
> В своём прототипе я это делал так:

so5::message_t играет практически такую же роль, как твои домены (см.свое
первое сообщение в данной теме).

Yauheni Akhotnikau

necitită,
17 feb. 2009, 15:14:5717.02.2009
– sobje...@googlegroups.com
On Tue, 17 Feb 2009 22:11:30 +0300, Dmitriy V'jukov <dvy...@gmail.com>
wrote:

> По поводу второго момента у меня некоторая


> неясность. Во-первых, как я понял под термином "агент" ты имеешь в
> виду то *класс* агента, то *инстанс* агента. Кто владеет сообщением -
> класс или инстанс? При посылке сообщения мы к имени приписываем имя
> класса или инстанса?

Под агентами я стараюсь понимать инстансы.

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

Да.

> Если выразить моё отношение в целом - то за отказ от владения, т.к.
> как мне сейчас видится - это достаточно сомнительная синтетическая
> абстракция.

Ну, может быть. Хотя она работала ;) Однако, всему есть предел :)))

> По поводу использования (1). При подключении плагина, он всё равно
> должен как-то "транспортировать" свою мета-информацию (о типах
> агентов, сообщений и т.д.) внутрь приложения; плюс, если он сам
> содержит статически влинкованный ран-тайм, то он должен переключить
> его на использование ран-тайма из приложения. Соотв. в этот момент
> можно и получить всю информацию о связи агентов и сообщений с
> конкретной DLL, т.е. если тип сообщения был экспортирован из DLL, то
> мы её не выгружаем, пока есть эти сообщения.

В случае с so_sysconf проблема была в том, что система плагинов была
самостоятельной, по отношению к ядру SObjectizer. Поэтому so_sysconf не
мог знать, есть ли в DLL что-то, что еще живет в run-time или нет.

> По поводу использования (2). Помнишь, я как-то тебя спрашивал
> используется ли в SO приложенииях динамеческая генерация типов
> сообщений, т.е. что-то типа "session/123/request"? Спрашивал я как раз
> с мыслью о сужении списка получателей при широковешательной рассылке.
> Насколько я помню, ты ответил, что нет, не используется. Но как я
> сейчас вижу, она всё-таки используется - динамической частью типа
> сообщения выступает имя владеющего агента. Правильно?

Динамической части *типа* сообщения нет. Есть динамическая часть полного
имени сообщения -- имя агента владельца. Например, если для сессии
создается агент с именем "session/123", то его сообщение request будет
иметь полное имя "session/123.request".

> Я в этом отношении пока пришёл к мысли о явном создании "доменов"
> обмена сообщеними. Всегда есть глобальный домен, так же можно
> создавать произвольное кол-во дополнительных доменов. Соотв. при
> подписке/отсылке сообщений указывается домен в котором идёт подписка/в
> который отправлять сообщение. Если домен не указывается, то
> используется глобальный. Домен хранит всю информацию о подписках -
> какой агент на сообщения какого типа подписан. Домен может быть
> глобальным, если определяет своё имя.

Ну как раз чем-то вроде домена должен быть экземпляр so5::message_t в моем
описании. Можно даже переименовать его в so5::message_domain_t, т.к. это
имя больше выражает смысл.

За message_domain_t не скрывается ничего, кроме самого простого описания.
А вот вся информация о подписке создается внутри run-time. И экземпляр
message_domain_t в таком случае будет ключем для доступа к этой информации.

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

Dmitriy V'jukov

necitită,
17 feb. 2009, 16:15:2517.02.2009
– SObjectizer
On 17 фев, 23:14, "Yauheni Akhotnikau" <eao...@intervale.ru> wrote:
> On Tue, 17 Feb 2009 22:11:30 +0300, Dmitriy V'jukov <dvyu...@gmail.com>  

> wrote:
>
> > По поводу второго момента у меня некоторая
> > неясность. Во-первых, как я понял под термином "агент" ты имеешь в
> > виду то *класс* агента, то *инстанс* агента. Кто владеет сообщением -
> > класс или инстанс? При посылке сообщения мы к имени приписываем имя
> > класса или инстанса?
>
> Под агентами я стараюсь понимать инстансы.


Всё-таки синтаксически сообщения принадлежат *классу* агента, и это
очень сбивает.

> > По поводу использования (1). При подключении плагина, он всё равно
> > должен как-то "транспортировать" свою мета-информацию (о типах
> > агентов, сообщений и т.д.) внутрь приложения; плюс, если он сам
> > содержит статически влинкованный ран-тайм, то он должен переключить
> > его на использование ран-тайма из приложения. Соотв. в этот момент
> > можно и получить всю информацию о связи агентов и сообщений с
> > конкретной DLL, т.е. если тип сообщения был экспортирован из DLL, то
> > мы её не выгружаем, пока есть эти сообщения.
>
> В случае с so_sysconf проблема была в том, что система плагинов была  
> самостоятельной, по отношению к ядру SObjectizer. Поэтому so_sysconf не  
> мог знать, есть ли в DLL что-то, что еще живет в run-time или нет.


А как тогда плагины общаются? Между ними сокеты открывается? Ведь
получается, что передавать объекты по-указателю тогда нельзя,
глобальные таблицы у плагина и у приложения разные - т.е. плагин
говорит отправить сообщение такому-то агенту, а ран-тайм плагина не
находит этого агента, т.к. он в ран-тайме приложения...
Я-то думал о каком-то явном объединении ран-таймов. Что-то типа: ран-
тайм предоставляет функции
all_meta_info_t offload_all_meta_info();
void load_all_meta_info(all_meta_info_t);
Соотв. у плагина дергаем offload_all_meta_info(), и передаём всю
информацию в приложение через load_all_meta_info().


>
> > По поводу использования (2). Помнишь, я как-то тебя спрашивал
> > используется ли в SO приложенииях динамеческая генерация типов
> > сообщений, т.е. что-то типа "session/123/request"? Спрашивал я как раз
> > с мыслью о сужении списка получателей при широковешательной рассылке.
> > Насколько я помню, ты ответил, что нет, не используется. Но как я
> > сейчас вижу, она всё-таки используется - динамической частью типа
> > сообщения выступает имя владеющего агента. Правильно?
>
> Динамической части *типа* сообщения нет. Есть динамическая часть полного  
> имени сообщения -- имя агента владельца. Например, если для сессии  
> создается агент с именем "session/123", то его сообщение request будет  
> иметь полное имя "session/123.request".


Но если мы создаём множество сообщений с именем "session/123.request",
но с разными данными, то "session/123.request" уже получается типом
сообщения...

> > Я в этом отношении пока пришёл к мысли о явном создании "доменов"
> > обмена сообщеними. Всегда есть глобальный домен, так же можно
> > создавать произвольное кол-во дополнительных доменов. Соотв. при
> > подписке/отсылке сообщений указывается домен в котором идёт подписка/в
> > который отправлять сообщение. Если домен не указывается, то
> > используется глобальный. Домен хранит всю информацию о подписках -
> > какой агент на сообщения какого типа подписан. Домен может быть
> > глобальным, если определяет своё имя.
>
> Ну как раз чем-то вроде домена должен быть экземпляр so5::message_t в моем  
> описании. Можно даже переименовать его в so5::message_domain_t, т.к. это  
> имя больше выражает смысл.


В MPI такие штуки называются коммуникаторами, если память не изменяет.
Хотя message_domain мне нравится, правда длинно...


> За message_domain_t не скрывается ничего, кроме самого простого описания.  
> А вот вся информация о подписке создается внутри run-time. И экземпляр  
> message_domain_t в таком случае будет ключем для доступа к этой информации.


По-сути, да. Хотя я бы предпочёл хранить информацию о подписке в самом
домене.


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


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


Mesajul a fost șters

Yauheni Akhotnikau

necitită,
17 feb. 2009, 17:11:4617.02.2009
– sobje...@googlegroups.com
On Wed, 18 Feb 2009 00:15:25 +0300, Dmitriy V'jukov <dvy...@gmail.com>
wrote:

> On 17 фев, 23:14, "Yauheni Akhotnikau" <eao...@intervale.ru> wrote:


>> On Tue, 17 Feb 2009 22:11:30 +0300, Dmitriy V'jukov <dvyu...@gmail.com>
>>  
>> wrote:
>>
>> > По поводу второго момента у меня некоторая
>> > неясность. Во-первых, как я понял под термином "агент" ты имеешь в
>> > виду то *класс* агента, то *инстанс* агента. Кто владеет сообщением -
>> > класс или инстанс? При посылке сообщения мы к имени приписываем имя
>> > класса или инстанса?
>>
>> Под агентами я стараюсь понимать инстансы.
>
>
> Всё-таки синтаксически сообщения принадлежат *классу* агента, и это
> очень сбивает.

А ты смотри на них, как на описания методов в C++ классе: нестатический
метод описывается в классе агента, но вызывается для экземпляра агента.
Т.е. запись:

class A {
public :
void do_something() { ... }
};
A a;
a.do_something();

является аналогом записи:

SOL4_CLASS_START(A)
SOL4_MSG_START( do_something, A::do_something )
SOL4_MSG_FINISH()
SOL4_CLASS_FINISH()
so_4::api::send_msg( "a", "do_something" );

Сообщение в SObjectizer4 удобно иногда рассматривать как нестатический
метод агента.

>> В случае с so_sysconf проблема была в том, что система плагинов была  
>> самостоятельной, по отношению к ядру SObjectizer. Поэтому so_sysconf не
>>  
>> мог знать, есть ли в DLL что-то, что еще живет в run-time или нет.
>
> А как тогда плагины общаются? Между ними сокеты открывается? Ведь
> получается, что передавать объекты по-указателю тогда нельзя,
> глобальные таблицы у плагина и у приложения разные - т.е. плагин
> говорит отправить сообщение такому-то агенту, а ран-тайм плагина не
> находит этого агента, т.к. он в ран-тайме приложения...
> Я-то думал о каком-то явном объединении ран-таймов. Что-то типа: ран-
> тайм предоставляет функции
> all_meta_info_t offload_all_meta_info();
> void load_all_meta_info(all_meta_info_t);
> Соотв. у плагина дергаем offload_all_meta_info(), и передаём всю
> информацию в приложение через load_all_meta_info().

Run-time у SObjectizer-а один. За макросами SOL4_CLASS_START/FINISH
скрываются глобальные переменные, которые в своих
конструкторах/деструкторах модифицируют системные словари SObjectizer4.
При загрузке очередной DLL запускаются конструкторы находящихся в ней
глобальных переменных, и с их помощью SObjectizer4 получает информацию о
классах агентов, находящихся в DLL.

Схема хоть и работает, имеет некоторые проблемы. Но работает.

> Но если мы создаём множество сообщений с именем "session/123.request",
> но с разными данными, то "session/123.request" уже получается типом
> сообщения...

Разные данные не могут быть. Структура сообщения всегда одна и та же. Т.е.
если есть:

class session_t : public so_4::rt::agent_t {
public :
struct msg_request {
std::string m_host;
std::string m_method;
};
...
};
SOL4_CLASS_START(session_t)
SOL4_MSG_START(request, session_t::msg_request)
SOL4_MSG_FINISH()
...
SOL4_CLASS_FINISH()

то у объектов session/123 и session/124 (если они оба имеют тип
session_t), не может быть разных типов сообщений request -- тип всегда
один: session_t::msg_request.

>> За message_domain_t не скрывается ничего, кроме самого простого
>> описания.  
>> А вот вся информация о подписке создается внутри run-time. И экземпляр  
>> message_domain_t в таком случае будет ключем для доступа к этой
>> информации.
>
>
> По-сути, да. Хотя я бы предпочёл хранить информацию о подписке в самом
> домене.

Ну это технический вопрос. Я бы хотел иметь тривиальные
конструкторы/деструкторы у глобальных объектов. Чтобы не иметь проблем с
загрузкой DLL под Windows. А хранение подписки в домене черевато
появлением нетривиального деструктора.

> Идея подписки по отправителю с одной стороны привлекательна, т.к.
> можно создать агента и подписаться именно на его сообщения, а он в
> свою очередь будет отправлять широковещательно. А с другой стороны я
> склонен рассматривать отправителя как деталь реализации, на которую
> порочно закладываться, т.к. агент вполне может делигировать отправку
> сообщения кому-то другому - собственно это и есть тот самый хороший
> loose coupling присущий системам с асинхронным сообщениями - т.е.
> просто мне пришло сообщение, кто когда и откуда его отправил меня не
> касается. А если начать закладываться на отправителей, то всё это
> может посыпаться...

Зато это будет удобно, имхо, при реализации flow-based приложений.

Răspundeți tuturor
Răspundeți autorului
Redirecționați
0 mesaje noi