SObjectizer
5.1
|
Краткое описание библиотеки so_sysconf_4.
Подсистема SO SysConf 4 (SObjectier System Configurator – сокращенно Sysconf), является приемником 2-го и 3-го (не публиковалась) поколения библиотеки Sysconf.
Sysconf предоставляет приложениям следующие возможности:
Типичное Sysconf-приложение представляет собой небольшой загрузчик и набор DLL с реализацией специфической прикладной логики. Причем зачастую большинство таких DLL – это вспомогательные и повторно используемые из других проектов (например, so_sysconf_log_3, so_sysconf_gemont_layer и т.п. ). А загрузчик представляет из себя небольшую программу, которая стартует SObjectizer Environment и подсистему Sysconf, после чего указывает Sysconf имя конфигурационного файла с описанием состава приложения и ожидает завершения работы SObjectizer. Основную часть работы по формированию приложения выполняет Sysconf во время разбора и обработки конфигурационного файла.
Кроме того Sysconf в своем составе предоставляет штатные приложения-загрузчики (so_sysconf_4: Штатные загрузчики).
По своей функциональности Sysconf является аналогом фреймворка System Configurator из состава библиотеки ACE. Но Sysconf появилась гораздо раньше, чем ACE начал использоваться в SObjectizer, и делалась с учетом особенностей SObjectizer. Поэтому Sysconf никак не использует System Configurator и является самостоятельной подсистемой.
Необходимость в подсистеме sysconf возникла из-за того, что одни и те же функции в разных случаях должны выполняться с помощью различных средств. Например, для установления SSL соединения можно использовать OpenSSL, GnuTLS или какую-либо коммерческую библиотеку. Для идентификации пользователя нужно либо спросить пароль, либо предложить составить изображение из предложенных фрагментов. Отправку уведомлений можно осуществлять либо через e-mail, либо через SMS. И т.д.
Если в приложении необходимо поддерживать несколько альтернативных возможностей, то возникает вопрос о том, как это сделать. Наиболее простой вариант заключается в том, чтобы на этапе трансляции и линковки исполнительного модуля собрать в единое приложение все необходимые библиотеки (как статические, так и динамические). Но этот способ имеет два важных недостатка:
Более сложный вариант состоит в том, чтобы разделить интерфейс и реализацию какой-либо функций на уровне используемых DLL-библиотек. Например, сделать интерфейс по поддержке SSL-соединений общим для различных реализаций. А сами реализации для OpenSSL и GnuTLS вынести в отдельные DLL. При этом исполнимый модуль не линкуется к реализациям вообще. Вместо этого при своем старте исполнимый модуль определяет, какую реализацию ему нужно использовать в конкретном случае (предположим, по конфигурационному файлу) и самостоятельно, вручную, загружает соответствующую DLL. Как только DLL с реализацией SSL-соединения окажется загруженной, конкретная реализация должна автоматически стать доступной для исполнимого модуля.
При реализации варианта с ручной загрузкой DLL так же существуют сложности. В основном, технического характера. Часть из них преодолевается достаточно просто (например, наличие различных API для работы с DLL в различных операционных системах). Наибольшую сложность вызывает, как правило, то, что после загрузки DLL реализация какой-либо функции должна стать доступной исполнимому модулю. Обычно это достигается использованием какой-либо таблицей доступных реализаций в исполнимом модуле. DLL либо сами прописывают себя в эту таблицу при загрузке (для чего могут использоваться либо глобальные переменные, либо точки входа/выхода в DLL). Либо исполнимый модуль сам определяет адрес какой-то интерфейсной функции в загруженной DLL.
В контексте SObjectizer-приложений Sysconf предполагает размещение средств создания коопераций и дополнительных слоев в различные DLL. Управление загрузкой/выгрузкой DLL и регистрацией/дерегистрацией коопераций средствами этих DLL и установкой слоев является задачей Sysconf. Это значит, что Sysconf берет на себя выполнения рутинных действий связанных с развертывание SObjectizer-инфраструктуры приложения.
Основным интерфейсом подсистемы so_sysconf_4 является слой so_sysconf_layer_t. Вызывая методы этого слоя, можно загружать/выгружать DLL библиотеки, регистрировать и дерегистрировать находящиеся в них кооперации, добавлять и регистрировать в системе SO дополнительные слои.
Предназначенные для использовани с sysconf DLL-библиотеки должны содержать в себе экспортируемую функцию следующего вида:
extern "C" { CPP_UTIL_2_EXPORT_FUNC_SPEC( so_sysconf_4::module_description_t * ) SYSCONF_MODULE_CALLING_CONVENTION so_sysconf_4_module_description() { std::unique_ptr< so_sysconf_4::std_module_description_t > module_desc_name( new so_sysconf_4::std_module_description_t ); module_desc_name->add_coop_handler(...); module_desc_name->add_coop_factory(...); module_desc_name->add_named_event(...); module_desc_name->add_layer_handler(...); return module_desc_name.release(); } }
Для упрощения работы с экспортируемой функцией so_sysconf_4 содержит ряд вспомогательных макросов. При их использовании пример выше примет следующий вид:
SYSCONF_4_MODULE_DESCRIPTION_START_STD() SYSCONF_4_MODULE_DESCRIPTION_ADD_HANDLER_STD(...) SYSCONF_4_MODULE_DESCRIPTION_ADD_FACTORY_STD(...) SYSCONF_4_MODULE_DESCRIPTION_ADD_EVENT_STD(...) SYSCONF_4_MODULE_DESCRIPTION_ADD_LAYER_HANDLER_STD(...) SYSCONF_4_MODULE_DESCRIPTION_FINISH_STD()
В качестве аргуметов макросам должны передаваться указатели на динамически созданные объекты классов-регистраторов коопераций, производные от coop_handler_t, coop_factory_t, средства добавления слоев – layer_handler_t, и именованные события – named_event_t. Т.е. на этапе разработки DLL необходимо определить, какие кооперации, именованные события и слои будут находиться в этой DLL. Поскольку в текущей версии sysconf нельзя в динамике изменить состав доступных sysconf коопераций в DLL.
Когда sysconf получает команду на загрузку DLL, указанная DLL загружается в память, и so_sysconf_4 получает список доступных регистраторов.
Все регистраторы коопераций и слоев ,а также именованные события во всех DLL должны иметь уникальные имена. Если при загрузке DLL вясняется, что в ней есть конфликтное имя, то загрузки DLL не происходит, а сообщение об ошибке пишется в журнал Sysconf.
Для регистрации/дерегистрации кооперации подсистеме sysconf выдаются специальные команды. Если регистрация кооперации прошла успешно, то sysconf увеличивает счетчик ссылок на DLL. Sysconf не позволяет выгрузить DLL с ненулевым счетчиком ссылок. При дерегистрации кооперации счетчик ссылок уменьшается.
Начиная с версии 4.0.0 в so_sysconf введена функциональность по добавлению дополнительных слоев SObjectizer. За добавление слоя отвечает класс layer_handler_t, в методе которого layer_handler_t::add() необходимо размещать код по добавлению дополнительных слоев.
Управлять подсистемой sysconf с помощью методов слоя so_sysconf_layer_t. Однако этот вариант не всегда слишком удобен из-за необходимости вызовов методов слоя в теле прикладной программы, а значи при необходимости изменения вызовов придется выполнять перекомпиляцию программы. К тому же, в большинстве случаев, нужно в начале работы по конфигурационному файлу определить, из чего будет состоять приложение, один раз загрузить все необходимые DLL и начать работу.
Для облегчения этой задачи sysconf поддерживает работу с конфигурационными файлами специального формата. Функция so_sysconf_layer_t::run_script() запускает на обработку указанный конфигурационный файл.
{sysconf-script [{load-dll <str-dll-file-name> {os-name-convert <"simple" or "none">} }]* [{reg-coop <str-coop-name> [{cfg-file <coop-cfg-file-name> }] }]* [{make-coop {factory <str-factory-name>} {coop <str-coop-name>} [{cfg-file <str-coop-cfg-file-name>}] }]* [{add-layer <str-layer-name> }] }
Вот пример реального конфигурационного файла для подсистемы sysconf.
{sysconf-script {load-dll "so_sysconf.breakflag_handler" {os-name-convert "simple"} } {reg-coop "so_sysconf_4::breakflag_handler::user_break_handler" } {reg-coop "so_sysconf_4::breakflag_handler::system_break_handler" } || || COOP_HANDLER || {load-dll "sample.so_sysconf_4.dll.coop_handler" {os-name-convert "simple"} {mandatory} } {reg-coop "coop_handler_sample::coop_handler" } {dereg-coop "coop_handler_sample::coop_handler" } {unload-dll "sample.so_sysconf_4.dll.coop_handler" {os-name-convert "simple"} } || || COOP_FACTORY || {load-dll "sample.so_sysconf_4.dll.coop_factory" {os-name-convert "simple"} } {make-coop {factory "coop_factory_sample::coop_factory"} {coop "unit_factory_1"} } {make-coop {factory "coop_factory_sample::coop_factory"} {coop "unit_factory_2"} } {make-coop {factory "coop_factory_sample::coop_factory"} {coop "unit_factory_3"} } {pause 3000 {comment "before dereg coop"} } {dereg-coop "unit_factory_1" } {dereg-coop "unit_factory_2" } {dereg-coop "unit_factory_3" } {unload-dll "sample.so_sysconf_4.dll.coop_factory" {os-name-convert "simple"} } || || NAMED_EVENT || {load-dll "sample.so_sysconf_4.dll.with_named_event" {os-name-convert "simple"} } {reg-coop "named_event_sample::coop_handler" } {wait-for "waiting_event" {timeout 3000} {comment "this one must succeed"} } {wait-for "never_event" {timeout 2000} {comment "this one must fail"} } {dereg-coop "named_event_sample::coop_handler" } {unload-dll "sample.so_sysconf_4.dll.with_named_event" {os-name-convert "simple"} } || || META_ACTION || {load-dll "sample.so_sysconf_4.dll.with_meta_action" {os-name-convert "simple"} } {reg-coop "meta_action_sample::coop_handler" } {make-coop {factory "meta_action_sample::coop_factory"} {coop "meta_action_sample::coop_factory"} } }
При использовании sysconf можно завершать работу SObjectizer вызовом метода so_5::rt::so_environment_t::stop() среды SO. Но sysconf предоставляет более развитые средства завершения работы SObjectizer Environment.
Иногда перед завершением работы приложения необходимо выполнить ряд сложных действий. Которые требуют времени и активного циркулирования сообщений в SObjectizer Environment. Например, при закрытии SMPP-соединения нужно выдать специальную команду unbind PDU и получить в ответ unbind_resp PDU. Что требует взаимодействия с агентами связи по TCP/IP. В этом случае нельзя начинать закрытие SMPP-соединения при получении so_5::rt::so_environment_t::stop(). Т.к. в этом случае работа SObjectizer Environment уже фактически завершена.
Слой sysconf содержит функциональность, задачей которой является управление процессом завершения работы SObjectizer Environment.
Каждый агент, который нуждается в специальных процедурах завершения работы должен зарегистрироваться в слое so_sysconf_layer посредством вызова метода so_sysconf_layer_t::subscribe_to_shutdown().
Для завершения работы SObjectizer необходимо вызвать метод so_sysconf_layer_t::stop(). После этого, всем агентам, зарегистрировавшихся в слое so_sysconf_layer отсылается сообщение msg_shutdown. Получив его, агентам нужно начать процедуру завершения своей работы. Когда эта процедура завершится агент должен вызвать метод слоя so_sysconf_layer_t::unsubscribe_from_shutdown().
Когда все зарегистрировавшиеся агенты отпишутся от оповещения о завершении работы, подсистема sysconf начнет завершение работы SObjectizer Environment посредством вызова so_5::rt::so_environment_t::stop().
Подсистема sysconf является "черным ящиком" – все управление осуществляется сообщениями. Снаружи sysconf сложно понять, что сейчас загружено и что зарегистрировано. Для получения информации о своем текущем состоянии sysconf предоставляет два механизма.
Первый состоит в том, что при изменении своего состояние sysconf рассылает сообщение so_sysconf_4::msg_sysconf_info, в котором перечисляются все загруженные в данный момент DLL и доступные кооперации со своим статусом. Запросить эту же информацию можно в любой момент, вызвав метод so_sysconf_layer_t::query_sysconf_info().
Второй механизм состоит в том, что подсистеме sysconf при старте может быть назначен специальный объект-журнализатор – объект производного от sysconf_logger_t типа. В этом случае при выполнении своих действий sysconf будет обращаться к журнализатору сообщая неформальное описание выполненого действия.
Механизм объекта-журнализатора может применяться для журналирования событий, происходящих с sysconf в подходящих для приложения хранилищах (текстовых файлах, базах данных, системых журналах Windows NT и т.д.).
Документация по SObjectizer v.5.1 'Джимара'. Последние изменения: Ср 15 Май 2013 12:56:21. Создано системой
![]() |
![]() |