Mbox-ы в SObjectizer используются для обобщенной реализации модели publish-subscribe. Причем mbox-ы расчитаны на то, что subscriber-ов будет несколько даже в случаях, когда subscriber по определению должен быть только один.
Например, допустим, что есть агент персонально которому должны отсылать сообщения. Решается это тем, что для агента создается mbox, на сообщения из которого подписывается только этот агент. Ссылки на этот mbox могут быть у разных агентов, но подписчик у mbox-а должен быть только один.
Здесь есть две проблемы.
Первая, не очень важная, состоит в том, что имея ссылку на mbox, можно подписаться на него. Намеренно или по ошибке, не суть важно. Это можно сделать. И кто-то еще будет получать сообщения, адресованные конкретному агенту.
Вторая, более важная, состоит в том, что даже когда получатель сообщений всего один, механизм диспетчеризации все равно работает по тому же алгоритму, что и в общем случае: со всеми необходимыми проверками и поиском списка получателей. Тогда как эффективнее было бы просто ставить сообщение в очередь единственного агента-получателя и все.
В связи с этим предлагаю обсудить идею создания нового типа mbox-ов, которые завязаны всего на одного агента-получателя.
Т.е. передача указателя на агент в метод create_local_mbox (как для анонимного, так и для именованного mbox-ов) предписывает environment-у создание mbox-а только для одного агента. Никакие другие агенты не смогут выполнять подписку на этот mbox.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Идея single subscriber -- хорошая. А по реализации мне кажется проще будет поступить так:
1. Да, реализуется отдельный интерфейс mbox-а, который может сделать получателем только одного агента.
2. Фиксировать агента-владельца mbox-а в момент первой подписки, тогда и тикетов не надо, тот кто попытается подписаться вторым получит исключение.
Если задать владельца сразу, то можно его зафиксировать и сразу, т.е. сделать 2-е реализации. Первая общая, где фиксируется в момент первой подписки и допускающей вариант:
1. A подписался
2. A отписался
3. B подписался
...
И на ее основе более узкую, коотрая фиксирует подписчика в конструкторе и не дает воплотить описанный выше сценарий.
Last edit: Nicolai Grodzitski 2014-07-04
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mbox-ы в SObjectizer используются для обобщенной реализации модели publish-subscribe. Причем mbox-ы расчитаны на то, что subscriber-ов будет несколько даже в случаях, когда subscriber по определению должен быть только один.
Например, допустим, что есть агент персонально которому должны отсылать сообщения. Решается это тем, что для агента создается mbox, на сообщения из которого подписывается только этот агент. Ссылки на этот mbox могут быть у разных агентов, но подписчик у mbox-а должен быть только один.
Здесь есть две проблемы.
Первая, не очень важная, состоит в том, что имея ссылку на mbox, можно подписаться на него. Намеренно или по ошибке, не суть важно. Это можно сделать. И кто-то еще будет получать сообщения, адресованные конкретному агенту.
Вторая, более важная, состоит в том, что даже когда получатель сообщений всего один, механизм диспетчеризации все равно работает по тому же алгоритму, что и в общем случае: со всеми необходимыми проверками и поиском списка получателей. Тогда как эффективнее было бы просто ставить сообщение в очередь единственного агента-получателя и все.
В связи с этим предлагаю обсудить идею создания нового типа mbox-ов, которые завязаны всего на одного агента-получателя.
В коде это может выглядеть, например, вот так:
Т.е. передача указателя на агент в метод create_local_mbox (как для анонимного, так и для именованного mbox-ов) предписывает environment-у создание mbox-а только для одного агента. Никакие другие агенты не смогут выполнять подписку на этот mbox.
Либо, еще как вариант для случая, когда нужно создать mbox-ы до создания агентов. В том числе и для ad-hoc агентов.
Вводится moveable-only тип direct_mbox_ticket_t:
Этот объект возвращается новыми методами класса so_environment_t:
Агент может стать владельцем такого mbox-а посредством метода so_take_direct_mbox():
Использоваться это может вот так с обычными агентами:
Либо, с ad-hoc агентами:
Идея single subscriber -- хорошая. А по реализации мне кажется проще будет поступить так:
1. Да, реализуется отдельный интерфейс mbox-а, который может сделать получателем только одного агента.
2. Фиксировать агента-владельца mbox-а в момент первой подписки, тогда и тикетов не надо, тот кто попытается подписаться вторым получит исключение.
API:
Если задать владельца сразу, то можно его зафиксировать и сразу, т.е. сделать 2-е реализации. Первая общая, где фиксируется в момент первой подписки и допускающей вариант:
1. A подписался
2. A отписался
3. B подписался
...
И на ее основе более узкую, коотрая фиксирует подписчика в конструкторе и не дает воплотить описанный выше сценарий.
Last edit: Nicolai Grodzitski 2014-07-04
Думаю, начать можно с того, чтобы добавить в agent_t метод:
который будет создавать и возвращать single subscriber mbox, владельцем которого будет тот агент, у которого вызвали этот метод.
А дальше уже смотреть, как делать тикеты или что-то подобное.
Я боюсь, что в многопоточной программе мы не всегда сможем гарантировать, что первый подписавшийся будет именно тем, кто нам нужен.