понедельник, 19 января 2015 г.

[prog.c++.sobjectizer] Еще одна идея по балансировке нагрузки на нескольких агентов

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

При выполнении запроса может потребоваться модификация состояния агента. Например, взаимодействие с удаленным узлом может быть многофазовым. Т.е. не просто подключились, отдали запрос, получили ответ, отключились. А чуть посложнее: подключились, отдали запрос, подождали какое-то время, запросили статус, подождали еще, запросили статус еще раз, затем запросили и получили результат. Между этими фазами нужно хранить какую-то специфическую для конкретного запроса информацию (идентификатор, последний полученный статус, величину тайм-аута и т.д.). Все это ведет к тому, что обработчики запросов у агента-performer-а будут not_thread_safe, что не позволит задействовать возможности adv_thread_pool-диспетчера.

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

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

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

Пока мысли крутятся вокруг специального типа mbox-а, т.е. какого-то нового, хитрого почтового ящика. Агент-collector отсылает в него сообщения-запросы, а вот получают эти сообщения не все агенты-performer-ы сразу, а только один из них.

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

  • можно не заморачиваться на такие вещи вообще, а переконфигурацию делать посредством жесткого рестарта кооперации агентов-performer-ов (т.е. сначала кооперация дерегистрируется, потом регистрируется заново, но уже с новыми параметрами). Тут от SObjectizer-а вообще ничего не требуется. Но для прикладного приложения это может быть самый плохой вариант, если перерегистрация -- это длительная операция, да еще и видимая снаружи (например, происходит переинициализация подключенного к компьютеру оборудования или же осуществляется переподключение к внешним системам);
  • заведение для нужд переконфигурации дополнительного mbox-а. Подойдет старый-добрый multi-producer/multi-consumer mbox, существующий с самой первой версии SObjectizer-5. В этом случае сообщения о переконфигурации отсылаются на mpmc-mbox, а сообщения-запросы на второй mbox, нового типа, предназначенный для распределения работы между агентами-близнецами. Тут так же от SObjectizer ничего не требуется, насколько удобно будет пользоваться в приложении несколькими mbox-ами -- вопрос. Может быть и не очень сложно;
  • можно в самом новом типе mbox-а указывать, каким образом должны диспетчироваться сообщения. Скажем, сообщения типа perform_job идут только на одного из агентов-близнецов. А сообщения reconfigure -- на всех сразу. В этом случае работа с агентами-близнецами должна быть наиболее простой, т.к. есть всего один mbox для взаимодействия с ними. Но реализация этого типа mbox-а будет несколько хитрее. И, может быть, про детали этой реализации вынуждены будут знать диспетчеры, дабы корректно доставлять сообщения до агентов-близнецов.

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

Отправить комментарий