Oberon space

General Category => Общий раздел => Тема начата: valexey_u от Февраль 01, 2013, 05:13:17 pm

Название: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 01, 2013, 05:13:17 pm
Вопрос собственно, наверно к Илье Ермакову: правильно ли я понимаю, что в в случае Message Bus, все сообщения сидят на стеке? Или они все же в массивах где-то в куче обитают?

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

Вообще, можешь краткий упрощенный пример того как это все используется накидать?
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 08:09:46 pm
Исходники же есть.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 01, 2013, 08:13:23 pm
Исходники же есть.
Реализаций оного Message Bus'а полно. Меня интересует не только реализация, но и применение.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 08:16:48 pm
Применяют ведь конкретную реализацию.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 01, 2013, 08:21:06 pm
Применяют ведь конкретную реализацию.
Применяют минимум три разные реализации (если судить по оберонкору).

Кроме того, меня не интересует все что связано с метапрограммированием, а те реализации это дело активно используют.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 08:28:18 pm
Как же ты без метапрограммирования модули обнаружишь? Будешь хуки везде таскать?
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 08:28:59 pm
А если ты про объекты, то посмотри на Views, там же везде сообщения.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 08:45:57 pm
Применяют минимум три разные реализации (если судить по оберонкору).
Я к тому, что применяют же реализацию, поэтому всё что тебя волнует можно реализовать как угодно.
Вот у отображений методы только для реализации, не вызвать их извне, только через сервис. А у модулей - экспортированная процедура - вызывай, кто хочешь.
Реализация Абф и наследники - не хранит сообщение и синхронно сливает его в хендлеры, реализация блаблабла - хранит сообщение и работает с массивами, организуя асинхронную рассылку и очередь.
Странно всё, короче.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 01, 2013, 08:50:46 pm
Применяют минимум три разные реализации (если судить по оберонкору).
Я к тому, что применяют же реализацию, поэтому всё что тебя волнует можно реализовать как угодно.
Вот у отображений методы только для реализации, не вызвать их извне, только через сервис. А у модулей - экспортированная процедура - вызывай, кто хочешь.
Реализация Абф и наследники - не хранит сообщение и синхронно сливает его в хендлеры, реализация блаблабла - хранит сообщение и работает с массивами, организуя асинхронную рассылку и очередь.
Странно всё, короче.
У Ильи была позиция "не мусорить", то есть его использование концепции таково, что сборщик мусора вообще никак не задействуется. Вот мне и интересны детали (как задач которые этим решаются, то есть применение, так и реализация). То есть самого механизма разбрасывания сообщений. Как именно хендлеры находят - не интересно.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 09:07:51 pm
через VAR параметр.
все могут дёргать всех, в том числе и прям из хендлера, одна месага инициирует отправку другой.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 01, 2013, 09:30:15 pm
через VAR параметр.
все могут дёргать всех, в том числе и прям из хендлера, одна месага инициирует отправку другой.
Я это понимаю, но хочется подробностей. Собственно список вопросов я уже озвучил в начале. Очевидно, что сообщения не могут быть тут на стеке если их непредсказуемо много. В общем, хочу деталей использования от Ильи.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 09:55:07 pm
Другой вопрос, зачем такое писать?
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 01, 2013, 09:56:05 pm
Другой вопрос, зачем такое писать?
Какое?
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 01, 2013, 10:05:47 pm
зачем работать с сообщениями до взрыва стека?
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: X512 от Февраль 02, 2013, 07:06:35 am
Вопрос собственно, наверно к Илье Ермакову: правильно ли я понимаю, что в в случае Message Bus, все сообщения сидят на стеке? Или они все же в массивах где-то в куче обитают?

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

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

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

Для сообщений ввода используется очередь сообщений Win32. При принятии сообщения оно конвертируется в родной формат в модуле HostWindows и передаётся в Views.ForwardCtrlMsg, который вызывает обработчики отображений. Можете поставить HALT(0) в какой-нибудь обработчик и посмотреть как происходит доставка сообщения.

Сообщения являются изменяемыми. Это активно используется в сообщениях свойств.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 02, 2013, 09:11:36 am
Вопрос собственно, наверно к Илье Ермакову: правильно ли я понимаю, что в в случае Message Bus, все сообщения сидят на стеке? Или они все же в массивах где-то в куче обитают?

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

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

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

То есть это выглядит примерно так?
PROCEDURE MessageSender
VAR
    msg : RECORD (GenericMessage) myField : INTEGER; processed : BOOLEAN END;
    i : INTEGER;
BEGIN
    msg.myField := 42;
    msg.processed := FALSE;
    WHILE i<LEN(Handlers) & ~msg.processed DO
        Handlers[i](msg);
        i := i+1;
    END;
END MessageSender;

Но тогда я не понимаю тезис про нагрузку на сборщик мусора - ведь при такой модели использования можно просто в куче создать по одному сообщению каждого типа и просто из повторно использовать. Даже если у нас типов сообщений действительно многого, штук 100, то все равно никакой значимой нагрузки на GC не будет. Да и аллокаций памяти не будет тоже.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: X512 от Февраль 02, 2013, 09:44:01 am
То есть это выглядит примерно так?
Примерно так. Только в BlackBox нигде processed и аналогов не используются. Сообщения шлются либо конкретно заданному объекту, либо всем видимым отображениям с заданной моделью (тупо перебираются все фреймы окна и сравнивается модель), либо всем отображениям, которые находятся в пути фокуса. Есть ещё другие специфичные варианты, здесь их рассматривать не будем. При посылке конкретно заданному объекту процедура посылки, это лишь небольшая обёртка, выполняющая проверки и прочие мелкие операции, например процедура посылки сообщения свойств:
PROCEDURE HandlePropMsg* (v: View; VAR msg: PropMessage);
VAR a: View; op: INTEGER;
BEGIN
IF ~(handler IN v.bad) THEN (* проверяем, что в раньше в обработчике v не было TRAP'а *)
a := actView; op := actOp; actView := v; actOp := handler; (* запоминаем отображение и тит обработчика *)
v.HandlePropMsg(msg); (* вызываем обработчик *)
actView := a; actOp := op (* возвращаем всё как было *)
END
END HandlePropMsg;

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

Тоесть имеется ввиду что-то вроде:
TYPE MouseMovedMsg* = POINTER TO RECORD x, y: INTEGER END; (* встроить тип в VAR нельзя, иначе нельзя будет привести к нему сообщение *)
VAR mouseMoved: MouseMovedMsg;

PROCEDURE SendMouseMoved*(t: Target; x, y: INTEGER);
BEGIN
  mouseMoved.x := x; mouseMoved.y := y;
  t.Handle(mouseMoved)
END SendMouseMoved;

BEGIN
  NEW(mouseMoved)
?
Такой подход может не сработать, если обработчик рекурсивно шлёт сообщение того-же типа. Да и громоздко всё это, но впринципе работать будет, если добавить проверки на вложенную посылку сообщений.

Подход со стеком выглядит намного проще, понятнее и привлекательнее.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: X512 от Февраль 02, 2013, 09:47:25 am
Насчёт тезисов: вы меньше OberonCore'а читайте, они пропогандируют то, что сами не понимают. Пытаются умолчать недостатки не понимая преемуществ.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 02, 2013, 10:06:53 am
То есть это выглядит примерно так?
Примерно так. Только в BlackBox нигде processed и аналогов не используются.
Ну, я просто пытался прикинуть зачем нужна может быть модификация сообщения обработчиком. По видимому, она может быть нужна для посылки ответа тому кто послал. Что я и смоделировал в простейшем случае.

Тоесть имеется ввиду что-то вроде:
TYPE MouseMovedMsg* = POINTER TO RECORD x, y: INTEGER END; (* встроить тип в VAR нельзя, иначе нельзя будет привести к нему сообщение *)
VAR mouseMoved: MouseMovedMsg;

PROCEDURE SendMouseMoved*(t: Target; x, y: INTEGER);
BEGIN
  mouseMoved.x := x; mouseMoved.y := y;
  t.Handle(mouseMoved)
END SendMouseMoved;

BEGIN
  NEW(mouseMoved)
?
Такой подход может не сработать, если обработчик рекурсивно шлёт сообщение того-же типа. Да и громоздко всё это, но впринципе работать будет, если добавить проверки на вложенную посылку сообщений.

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

Впрочем, я кажется понимаю в чем проблема такого подхода - кто-нибудь может взять, и сохранить переданный ему указатель на сообщение для неких своих нужд. В результате получим не предсказуемое поведение - любое сообщение может быть модифицировано в любой момент времени непредсказуемым образом.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: X512 от Февраль 02, 2013, 10:22:45 am
Да, имеется ввиду именно такое. На счет рекурсивной отправки - было же сказано, что и в случае стека этим лучше не пользоваться. Впрочем, для такого подхода (через кучу) это решаемая проблема - делаем фабрику повторно используемых объектов, у которой при отправке просим выдать нам свободный экземпляр сообщения данного типа.

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

Зачем делать пулы (избыточная сложность на пустом месте, к тому же добавление новых типов сообщений станет большой проблемой) я не понимаю, чем стек не угодил? Или в ваших Java/C# нет объектов на стеке и нужно делать костыли? Относительно непредсказуемого поведения: можно ведь передавать сообщение обработчику через VAR параметр, а не указатель и тогда проблем не будет. Или в Java/C# их нет?

Всё-же я не понимаю зачем использовать кучу вместо стека...
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 02, 2013, 10:26:03 am
Да, имеется ввиду именно такое. На счет рекурсивной отправки - было же сказано, что и в случае стека этим лучше не пользоваться. Впрочем, для такого подхода (через кучу) это решаемая проблема - делаем фабрику повторно используемых объектов, у которой при отправке просим выдать нам свободный экземпляр сообщения данного типа.

Впрочем, я кажется понимаю в чем проблема такого подхода - кто-нибудь может взять, и сохранить переданный ему указатель на сообщение для неких своих нужд. В результате получим не предсказуемое поведение - любое сообщение может быть модифицировано в любой момент времени непредсказуемым образом.
Рекурсия хоть и не рекомендуется, но и не запрещена. В BlackBox рекурсия посылок сообщений иногда используется. Зачем делать пулы (избыточная сложность на пустом месте, к тому же добавление новых типов сообщений станет большой проблемой) я не понимаю, чем стек не угодил? Или в ваших Java/C# нет объектов на стеке и нужно делать костыли? Относительно непредсказуемого поведения: можно ведь передавать сообщение обработчику через VAR параметр, а не указатель и тогда проблем не будет. Или в Java/C# их нет?
Гм. Мысль хорошая. Я буду её думать. Спасибо. Может за выходные что-то напишу.

Всё-же я не понимаю <b>зачем</b> использовать кучу вместо стека...
Я исследую применимость подобных механизмов в других языках.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 02, 2013, 11:15:57 am
Я на джаве такое пилил, оно даже работает, почти так же как на ББ, через синглтон-менеджер и сообщения с конструктором, хыхы.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 02, 2013, 11:16:42 am
Насчёт тезисов: вы меньше OberonCore'а читайте, они пропогандируют то, что сами не понимают. Пытаются умолчать недостатки не понимая преемуществ.
Обжигающая Правда от Профессионалов4Fun
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 02, 2013, 01:11:33 pm
Насчёт тезисов: вы меньше OberonCore'а читайте, они пропогандируют то, что сами не понимают. Пытаются умолчать недостатки не понимая преемуществ.
Обжигающая Правда от Профессионалов4Fun
Боже, это же сознательное снижение уровня дискуссии!!!11 :-D

Но коль уж перешли на личности, X512, кем бы он ни был в реальности, оставляет впечатление исключительно грамотного человека использующего в повседневной работе КП вообще, и ББ в частности.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 02, 2013, 02:39:21 pm
Пара цитат:
Насчёт тезисов: вы меньше OberonCore'а читайте, они пропогандируют то, что сами не понимают. Пытаются умолчать недостатки не понимая преемуществ.
Вот сознательное снижение уровня.
Цитировать
пропогандируют
А вот и исключительный уровень грамотности :D
Но в главном-то он прав!
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 02, 2013, 07:20:18 pm
Я на джаве такое пилил, оно даже работает, почти так же как на ББ, через синглтон-менеджер и сообщения с конструктором, хыхы.
Как там решалась обозначенная мною проблема?
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: kkk от Февраль 02, 2013, 07:44:42 pm
Да никак не решалась, сообщения нигде не хранились и создавались перед отправкой, затем передавались в синглтон где и рассылались всем зарегистрированным объектам по порядку.
В планах было ещё запилить проверку на зацикливания и прочее, но мне было решительно лень. Да и джава надоела в тот момент.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: Илья Ермаков от Февраль 02, 2013, 08:56:01 pm
2 valexey:

Во-первых, есть механизм передачи сообщения (ещё не bus) - VAR-параметр полиморфного типа. Это можно рассматривать как средство введения, в нужный момент в нужных местах, динамического ("утиного") ООП. И название "сообщение" здесь, в принципе, уже правомерно, на аналогии с ООП Смоллтока, например - где шлётся произвольное сообщение, а объект, если может, его обрабатывает.

Традиционный bus возникает в обероновском ГУЕ - и заключается в иерархической передаче сообщения по дереву граф. объектов с помощью вызова методов с полиморфным параметром.
Никакого хранения, асинхронности и проч. тут нет - но название "шина" правомочно в силу принципа действия: "послали сообщение в среду распространения - оно там само гуляет до тех пор, пока кто-то не обработает".

В принципе, дальше, при желании иметь какие-то асинхронные очереди, можно брать сам способ представления сообщений (расширяемыми записями) и обработки (процедура с полиморфным параметром) и добавлять какие-то службы хранения и передачи.
Для избежания использования кучи нужно иметь свои байтовые буферы, в которые можно записывать-считывать записи. Для контроля типов при такой сериализации можно писать перед записью тег - fingerprint её типа.
Для передачи в функцию-обработчик можно формировать на стеке побайтно "образ" её кадра и вызывать (для реализации такой системной службы позволительны такие штуки).
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: valexey_u от Февраль 04, 2013, 12:04:07 pm
Илья, спасибо большое за ответы.

Но справедливости ради, вставлю пару коментариев:

Во-первых, есть механизм передачи сообщения (ещё не bus) - VAR-параметр полиморфного типа. Это можно рассматривать как средство введения, в нужный момент в нужных местах, динамического ("утиного") ООП.  И название "сообщение" здесь, в принципе, уже правомерно, на аналогии с ООП Смоллтока, например - где шлётся произвольное сообщение, а объект, если может, его обрабатывает.
Все же к утиной типизации и к сообщениям smalltalk'а это не имеет отношения. В случае утиной типизации, да и смаллтолковых сообщений нет древовидной иерархии наследования оных сообщений/типов. Наиболее близко к этому - структурная типизация. А тут у нас все же проверка идет по имени типа сообщения, а не по структуре сообщения. Это принципиальная разница.

Ну а так да, вызов любой процедуры с аргументами можно назвать посылкой сообщения данному куску кода :-) Впрочем, это уже терминологические игры.
Название: Re: [CP] Вопрос про Message Bus.
Отправлено: Губанов Сергей Юрьевич от Февраль 04, 2013, 12:46:27 pm
Впрочем, я кажется понимаю в чем проблема такого подхода - кто-нибудь может взять, и сохранить переданный ему указатель на сообщение для неких своих нужд.
Расскажу про свою библиотеку Intercom (на C#). У меня сообщение передаётся во владение. Хочешь сохраняй, не хочешь - вызывай Dispose. В Dispose объект сообщения помещается в кэш для повторного использования. Кэш в принципе бесконечный, но раз в минуту он очищается на 10%. Есть два типа диспетчеров службы доставки сообщений: однопоточный и многопоточный. Многопоточный диспетчер может доставить одному и тому же получателю несколько сообщений одновременно. Объекты-получатели для того чтобы стать получателями должны зарегистрироваться в диспетчере. При регистрации им выдаётся интеркомный адрес Intercom.Id. Это 8 байтовое число, в котором закодирован диспетчер и номер зарегистрированного объекта. Отправка сообщения осуществляется по идентификатору Intercom.Id получателя.

Intercom.SendMessage(идентификатор_получателя, указатель_на_сообщение);

Отправляемое сообщение ставится в очередь. Затем из потока(потоков) диспетчера доставляется. Получатель может разрегистрироваться, тогда во время доставки диспетчер не найдёт объекта с указанным Intercom.Id, в этом случае у сообщения будет вызван Dispose самим диспетчером. У однопоточного диспетчера реализована возможность широковещательной рассылки сообщения всем зарегистрированным в этом диспетчере подписчикам. Это сообщение диспозится самим диспетчером, получатели не должны изменять широковещательные сообщения. Сообщения бывают первого и второго сорта (приоритета). В среднем, на каждые 10 сообщений первого сорта (если они есть) будет обработано 1 сообщение второго сорта (если оно есть). Имеется встроенный неотключаемый профилировщик, который постоянно измеряет сообщения каких типов каким типам получателей сколько раз в секунду доставляются и сколько времени обрабатываются. Измеряется длина очередей (первого и второго сорта) в секундах (латентность). Скорость отправки сообщений, скорость доставки (когда система перегружена первая скорость будет больше второй, а очередь будет расти). Программа использующая Intercom знает сколько времени сообщения простаивают в очереди (латентность) и может регулировать нагрузку. Если речь о телефонных звонках, то программа может режектить лишние телефонные звонки адаптируясь под быстродействие железа, удерживая латентность (время отклика) в заданных пределах. Имеется встроенный неотключаемый контролёр, который следит за зависаниями. Если кто-то получая сообщение слишком долго не возвращает управление, то контролёр (у него отдельный поток) печатает в журнал тип сообщения, тип получателя и сколько секунд уже тянется получение сообщения, ругаясь на то, что возможно программа зависла. Через определённый большой таймаут (убедившись, что поток точно завис и терять уже нечего кроме своих цепей) контролёр делает попытку абортировать поток диспетчера с целью получить стэк трэйс того места кода где произошло зациклиливание.

namespace MeraSystems
{
  public static partial class Intercom
  {
    public static void Subscribe (Dispatcher d, Object obj);
    public static void Unsubscribe (Object obj);
    public static void SendMessage (Id intercomId, Message message);
    public static void SendSecondGradeMessage (Id intercomId, Message message);
    public static void BroadcastMessage (Dispatcher dispatcher, Message message);
    public static void BroadcastSecondGradeMessage (Dispatcher dispatcher, Message message);
    public static void Terminate ();
    public static Dispatcher CreateDispatcher (string name, SinglethreadHook hook);
    public static Dispatcher CreateDispatcher (string name, MultithreadHook hook, int minThreadCount, int maxThreadCount);
    public static void WriteReport (System.Collections.Generic.List<string> report); // отчёт профилировщика
  }
}