Файл: Технология CORBA (Теоретические аспекты).pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 01.04.2023

Просмотров: 114

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Необходимо помнить, что одно и тоже приложение способно являться как клиентом, так и сервером – CORBA в данном случае не определяет каких-либо ограничений.

Разработанный выше объект (не сервант, а сам CORBA-объект) является объектом временным. Это говорит о том, что он не способен функционировать дольше, чем работает элемент CORBA, создавший его. В проанализированном примере данный компонент явно не пнаходился в программе, и подобный способ создания CORBA-объекта нередко именуют «неявным». В реальных программах многие из CORBA-объектов разрабатываются иначе.

Компонент CORBA, отвечающий за разработку CORBA-объектов, их сервантов, поддерживающий связь между ними и участвующий в доставке вызова клиента нужному серванту, именуется объектным адаптером.

Стандарт CORBA дает возможность иметь и применять несколько разных объектных адаптеров. Сейчас есть 2 стандартных объектных адаптера – BOA (Basic Object Adapter) и POA (Portable Object Adapter). Применение BOA признано устаревшим, поскольку это не дает возможности реализовать переносимость серверных CORBA-приложений. В следующей главе курсовой работы рассмотрен объектный адаптер POA.

2 Практическая реализация объектного адаптера

2.1 Описание РОА

В реальных CORBA-приложениях применяется древовидная иерархия объектных адаптеров. В корне ее расположен Root POA – объектный адаптер по умолчанию. Программист получает доступ к объектному адаптеру при помощи стандартного кода, применяемого в различных ситуациях:

CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

CORBA::Object_var rpObj =

orb->resolve_initial_references("RootPOA");

PortableServer::POA_var rootPoa = PortableServer::POA::_narrow(rpObj);

Дочерние POA образуются при помощи обращения к уже созданным POA как к фабрикам. Необходимо учитывать, что дочерний POA не наследует свойств своего базового POA – набор свойств для каждого создаваемого объектного адаптера необходимо определять явно. Так, если нужно образовать «долгоживущие» объекты, то сперва необходимо разработать соответствующий POA.

Перед разработкой дочерних POA целесообразно образовать так называемый «менеджер» POA. Он несет ответственность за распределение клиентских запросов между сервантами, состоящими под управлением различных POA, а также за управление их (POA) циклом жизни. Фабрикой данного менеджера способен являться Root POA. При образовании дочерних объектных адаптеров необходимо указать менеджер POA в качестве аргумента. Если не был создан собственный менеджер, и вместо его имени при вызове метода создания POA был указан nil, то будет неявно создан и применен менеджер по умолчанию.


Процесс уничтожения объектных адаптеров осуществляется по установленному алгоритму – сперва дочерние POA, далее их «родители».

Теперь рассмотрим процесс создания объекта с применением РОА.

Рассмотрим пример создания объекта с применением myPOA. С каждым CORBA-объектом необходимо сравнить «ключ» – идентификатор, дающий возможность однозначным образом идентифицировать данный объект. Далее нужно явно задать идентификатор. Для этого необходимо вызвать метод, дающий возможность создать данный идентификатор на основе строки.

PortableServer::ObjectId_var objID =

PortableServer::string_to_ObjectId ("MyObject");

Последующие две команды создают сервант, а далее и CORBA-объект с определенным ObjectID:

MyInterfaceImpl servant;

myPOA->activate_object_with_id (objID, &servant);

Наконец, для начала обработки запросов от клиента необходимо активизировать менеджер POA:

poaMngr->activate();

Практику, когда для каждого CORBA-объекта при запуске приложения образуется свой сервант, нельзя признать удачной – так можно потратить огромное количество ресурсов. Разработчик способен образовывать CORBA-объекты и без создания сервантов. Сделать это несложно:

myPOA->create_reference_with_id(

objID, "IDL:MyInterface:1.0");

Сопоставить с таким объектом сервант можно позднее, причем разнообразными способами.

В CORBA присутствуют команды создания объектов, но нет команды их уничтожения. Сделано это ввиду того, что очень сложно отыскать определенный элемент CORBA, который взял бы на себя «труд» надежного и безопасного уничтожения объектов. Поэтому под уничтожением объекта понимается определенная последовательность действий, ведущих к тому, что ни один клиент по имеющимся у него объектным ссылкам не может получить доступ к CORBA-объекту.

Рассмотрим, что происходит при временном объекте, созданного ранее с помощью вызова метода _this(). Объектная ссылка на этот объект, переданная клиенту через файл, включает имя хоста, на котором было запущено создавшее объект приложение, использованный порт TCP/IP, уникальный идентификатор объекта. Это свидетельствует о том, что клиент способен применять имеющуюся у него объектную ссылку лишь до тех пор, пока серверное приложение работает и в нем находится создавший объект объектный адаптер.

При остановке и дальнейшем запуске этого же приложения на том же компьютере будет образован новый CORBA-объект – его собственный идентификатор и идентификатор его POA будут отличаться от тех, данные для которых присутствуют в «старой» объектной ссылке. Это говорит о том, что по ней получить доступ к «старому» объекту по сути невозможно. В такой ситуации говорят, что CORBA-объект больше не существует. Клиент может «выбросить» имеющуюся у него объектную ссылку – она теперь не нужна.


При применении долгоживущих объектов ситуация осложняется. Даже если объект разработан при помощи POA, необходимого для создания и управления persistent-объектами, это не значит, что после остановки серверного приложения клиент будет в состоянии вызвать удаленные методы по существующей объектной ссылке. В простейшем случае каких-либо проблем не возникнет, если серверное приложение снова запущено «вручную» на том же хосте и с применением того же порта TCP/IP.

2.2 Свойства POA

Возможность явного указания того, является ли CORBA-объект временным или долгоживущим – это лишь одна из стандартных возможностей POA. Определяется она так:

module PortableServer

{

enum LifeSpanPolicyValue { TRANSIENT, PERSISTENT };

interface LifeSpanPolicy : CORBA::Policy

{

readonly attribute LifeSpanPolicyValue;

};

Остальные опции рассмотрены ниже.

Режим управления заданием идентификатора объекта (IdAssignmentPolicyValue). Вероятные значения – USER_ID или SYSTEM_ID. В первом случае идентификатор объекта задает сам пользователь, во втором – он автоматически создается POA.

Режим поддержки одним сервантом нескольких CORBA-объектов (IdUniquenessPolicyValue). Вероятные значения – UNIQUE_ID (один сервант является инкарнацией лишь одного CORBA-объекта) и MULTIPLE_ID (один сервант способен обслуживать несколько объектов).

Режим разрешения неявной активации (ImplicitActivationPolicyValue). Вероятные значения – IMPLICIT_ACTIVATION (неявное создание CORBA-объекта, например, с помощью _this(), допускается) и NO_IMPLICIT_ACTIVATION (нужно создавать CORBA-объекты явно).

Режим создания и управления сервантами (RequestProcessingPolicyValue). Здесь необходимо привести более подробные пояснения.

В принципе, вероятны лишь два режима создания сервантов: серванты образуются в программе или явно (как в ранее рассмотренных примерах), или в ходе поступления клиентских запросов – вероятно, даже для обслуживания одного-единственного запроса. POA реализует поддержку обоих режимов.

Прежде всего, POA способен включать Active Object Map (AOM), т.е. массив указателей на уже созданные серванты. «Индексом» данного массива является показатель Object ID. В данный массив могут попадать как серванты, образованные программистом, так и серванты, динамически образованные объектным адаптером.

При динамическом создании сервантов предусмотрено два отдельных режима – Activation-режим и Location-режим. Activation-режим состоит в том, что при поступлении клиентского запроса POA сперва ищет релевантный сервант в AOM, и только если ничего не нашлось, то сервант динамически создается POA, а далее указатель на него помещается в AOM. Location-режим не «смотрит» в AOM – AOM вообще не поддерживается в таком режиме – а образует сервант для обслуживания пришедшего вызова и далее его уничтожает.


Процесс динамического создания сервантов состоит в том, что POA вызывает определенные написанные программистом функции. Естественно, данные функции нужно зафиксировать в POA – для такой ситуации предполагаются специальные команды.

Вместе с тем предусмотрен определенный вспомогательный, но в иногда очень удобный режим – «сервант по умолчанию». Смысл данного режима заключается в том, что программист явно создает один-единственный сервант и фиксирует его как сервант, являющийся инкарнацией всех CORBA-объектов. Например, для взаимодействия с базой данных программист создает сотни, тысячи или миллионы CORBA-объектов – по одному на каждую запись, а затем создает один сервант, не имеющий своего состояния, обслуживающий объекты в совокупности. Состояние каждого CORBA-объекта просто извлекается из установленной записи базы данных.

Итак, вероятные значения опции RequestProcessingPolicyValue следующие:

  • USE_ACTIVATE_OBJECT_MAP_ONLY – возможно лишь явное создание сервантов с помещением указателей на них в AOM;
  • USE_DEFAULT_SERVANT – режим применения серванта по умолчанию;
  • USE_SERVANT_MANAGER – применение или Activation-режима (если опция ServantRetensionPolicyValue присвоено значение RETAIN), или Location-режима (если ServantRetensionPolicyValue присвоено значение NON_RETAIN);
  • режим обеспечения соответствия между сервантами и CORBA-объектами (ServantRetensionPolicyValue). Вероятные значения – RETAIN (сохранять информацию о серванте в Active Object Map) и NON_RETAIN (применять вновь создаваемый сервант лишь однажды);
  • применение потоков (ThreadPolicyValue). Вероятные значения – ORB_CTRL_MODEL (применять потоковую модель, устанавливаемую ORB) и SINGLE_THREAD_MODEL (один поток обслуживает все запросы клиентов к сервантам данного POA).

2.3 Установка связи между клиентом и серверным объектом

После знакомства с объектными ссылками очевидно, что определение связи между клиентом и серверным объектом состоит в получении клиентом объектной ссылки на данный объект. Конечно, передача объектной ссылки через файл пусть и вероятна, но не способна считаться удобным и универсальным способом.

В CORBA используется 2 ключевых стандартных способа, дающих возможность сделать серверный объект доступным для клиента, т.е. передать клиенту объектную ссылку на данный объект. Один из таких способов касается применения Сервиса Имен (Naming Service), второй – Трейдер-Сервиса.


Помимо стандартных служб, немало производителей создают и поставляют собственные поисковые средства. Для VisiBroker’а подобным средством является Location Service, основанный на применении Smart Agent. Т.к. VisiBroker представляет собой одну из самых распространенных реализацией ORB, то целесообразно рассмотреть данный процесс.

Гибкость и эффективность любой технологии создания распределенных систем существенно зависит от поддерживаемого данной системой набором типов данных. Далее отражены ключевые положения, определяющие управление типами в CORBA.

  • CORBA поддерживает базовые типы данных (octet, short, unsigned short, long, unsigned long, long long, unsigned long long, fixed, float, double, long doublе и т.д.), так называемые «сконструированные» типы данных (массивы, структуры, объединения, последовательности и типы-значения) и объектные ссылки. Помимо всего прочего, поддерживаются «синонимы типов», образующиеся при помощи typedef.
  • Любой из данных типов может быть описан на языке IDL.
  • С каждым типом сравнены метаданные, т.е. признак типа и дополнительная информация, вид которой находится в зависимости от определенного типа. Как метаданные, так и объекты любого типа способны создаваться динамически, т.е. без помощи IDL.
  • Есть тип any, способный хранить данные любого типа.

Для увеличения переносимости C++-программ на разные платформы и ОС (на уровне исходного кода) вместо определенных имен типов C++ – short, unsigned long, wchar_t, char*, bool и пр. – применяются typedef-алиасы, например, CORBA::Short, CORBA::ULong, CORBA::WChar, CORBA::String_ptr, CORBA::Boolean. Применение typedef-алиасов при разработке CORBA-программ значительно облегчает их создание, особенно потому, что вместе с такими алиасами интенсивно применяются и вспомогательные классы, например, CORBA::String_var. Типы, имена которых заканчиваются на _var или _out, являются крайне полезными и удобными, хотя практически в каждой ситуации можно обойтись и без них.

Типы _ptr не представляют ничего интересного – это всего лишь typedef-синоним для указателя:

typedef unsigned long CORBA::ULong;

typedef CORBA::ULong* CORBA::ULong_ptr;

Совсем другое дело – _var-классы.

_var-классы

_var-классы являются исключительно сервисными классами. Эти классы являются оболочками вокруг типов, описанных на IDL. По сути их можно рассматривать как «разумные» указатели (smart pointer) – данные классы реализуют освобождение занятых ранее ресурсов при их уничтожении или при осуществлении операций присваивания. Приведем пример использования строк: один вариант – в классическом стиле C++, другой – с использованием _var-класса CORBA.