Возникают вопросы:
При этом может быть желательно сначала создать объект db_connection, попытаться установить соединение с БД и, только если это удалось, создать динамическую кооперацию.
Так же может оказаться, что некоторые из агентов должны использовать объект db_connection в своем конструкторе, а некоторые в своем деструкторе. Но SObjectizer не определяет порядка, в котором агенты будут уничтожены. Поэтому, владельцем объекта db_connection должен быть объект, время жизни которого больше, чем время жизни любого из агентов динамической кооперации. Таким агентом может являться сама динамическая кооперация.
При дерегистрации динамической кооперации SObjectizer самостоятельно уничтожает объекты-агенты и объект-кооперацию. При этом гарантируется, что агенты будут уничтожены до кооперации. Это означает, что можно попытаться сохранить объект db_connection в динамической кооперации. В SObjectizer v.4.2.6 сделать это можно двумя способами.
Во многих случаях вместе с кооперацией нужно будет сохранять объекты, которые нельзя сделать производными от so_4::rt::dyn_coop_controlled_obj_t. Например, тот же объект db_connection. В этом случае на помощь приходит шаблон-адаптер so_4::rt::dyn_coop_controlled_templ_t и вспомогательная шаблонная функция so_4::rt::dyn_coop_controlled():
// Функция создания динамической кооперации // которая должна осуществлять работу с указанной // базой данных. // В случае ошибок порождаются исключения. void create_db_coop( // Имя кооперации. const std::string & coop_name, // Параметры подключения к БД. const db_connection_params_t & connection_params ) throw( std::exception ) { // Для очистки ресурсов при исключениях // используется std::auto_ptr // Подключение к БД. std::auto_ptr< db_connection_t > db_connection_ptr( new db_connection_t( connection_params ) ); // Соединение с БД установлено. Создание агентов. std::auto_ptr< a_reader_t > a_reader_ptr( coop_name + "::a_reader", new a_reader_t( *db_connection ) ); std::auto_ptr< a_writter_t > a_writter_ptr( coop_name + "::a_writter", new a_writter_t( *db_connection ) ); std::auto_ptr< a_handler_t > a_handler_ptr( coop_name + "::a_handler", new a_handler_t( *db_connection ) ); // Агенты созданы. Создание кооперации. so_4::rt::agent_t * agents[] = { a_reader_ptr.release(), a_writter_ptr.release(), a_handler_ptr.release() }; so_4::rt::dyn_agent_coop_t * my_coop = new so_4::dyn_agent_coop_t( coop_name.c_str(), agents, sizeof( agents ) / sizeof( agents[ 0 ] ) ); so_4::rt::dyn_coop_controlled( *my_coop, db_connection_ptr.release() ); // Регистрация кооперации. so_4::rt::dyn_agent_coop_helper_t helper( my_coop ); if( helper.result() ) // Кооперация не зарегистрирована. throw std::runtime_error( "unable to register cooperation" ); }
Можно сделать класс, производный от so_4::rt::dyn_agent_coop_t, который в своем деструкторе уничтожит объект db_connection.
Например такого класса кооперации:
class my_dyn_coop_t : public so_4::rt::dyn_agent_coop_t { typedef so_4::rt::dyn_agent_coop_t base_type_t; private : std::auto_ptr< db_connection_t > m_db_connection_ptr; public : my_dyn_coop_t( const char * coop_name, so_4::rt::agent_t ** agents, size_t agent_count, db_connection_t * db_connection ) : base_type_t( coop_name, agents, agent_count ), m_db_connection_ptr( db_connection ) { } virtual ~my_dyn_coop_t() { // Объект db_connection будет уничтожен // классом std::auto_ptr } };
Пример использования подобного класса:
// Функция создания динамической кооперации // которая должна осуществлять работу с указанной // базой данных. // В случае ошибок порождаются исключения. void create_db_coop( // Имя кооперации. const std::string & coop_name, // Параметры подключения к БД. const db_connection_params_t & connection_params ) throw( std::exception ) { // Для очистки ресурсов при исключениях // используется std::auto_ptr // Подключение к БД. std::auto_ptr< db_connection_t > db_connection_ptr( new db_connection_t( connection_params ) ); // Соединение с БД установлено. Создание агентов. std::auto_ptr< a_reader_t > a_reader_ptr( coop_name + "::a_reader", new a_reader_t( *db_connection ) ); std::auto_ptr< a_writter_t > a_writter_ptr( coop_name + "::a_writter", new a_writter_t( *db_connection ) ); std::auto_ptr< a_handler_t > a_handler_ptr( coop_name + "::a_handler", new a_handler_t( *db_connection ) ); // Агенты созданы. Создание кооперации. so_4::rt::agent_t * agents[] = { a_reader_ptr.release(), a_writter_ptr.release(), a_handler_ptr.release() }; my_dyn_coop_t * my_coop = new my_dyn_coop_t( coop_name.c_str(), agents, sizeof( agents ) / sizeof( agents[ 0 ] ), db_connection_ptr.release() ); // Регистрация кооперации. so_4::rt::dyn_agent_coop_helper_t helper( my_coop ); if( helper.result() ) // Кооперация не зарегистрирована. throw std::runtime_error( "unable to register cooperation" ); }
Документация по SObjectizer v.4.4 'Тебуломста'. Последние изменения: Thu Sep 18 10:26:48 2008. Создано системой 1.5.6 |