Tuxedo CORBA サーバ アプリケーションの開発方法

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

Basic CORBA サーバ アプリケーションの設計と実装

この章では、Basic University サンプル アプリケーションを例として使用して、CORBA サーバ アプリケーションを設計および実装する方法について説明します。この章の内容は、実装するアプリケーションの設計が完了し、OMG IDL に定義されていることを前提にしています。この章では、サーバ アプリケーション向けの設計および実装の選択肢に焦点を当てます。

ここでは、以下の内容について説明します。

 


Basic University サンプル アプリケーションのしくみ

Basic University サンプル アプリケーションを使用すると、学生は中央の University データベースからコース情報を参照できます。この Basic サンプル アプリケーションでは、学生は次のことを行うことができます。

Basic University サンプル アプリケーションの OMG IDL

Basic University サンプル アプリケーションの OMG IDL ファイルには、次のインタフェースが定義されます。

インタフェース
説明
オペレーション
RegistrarFactory
Registrar オブジェクトのオブジェクト参照を作成する。
find_registrar()
Registrar
データベースからコース情報を取得する。
get_courses_synopsis()
get_courses_details()
CourseSynopsisEnumerator
検索基準に一致するコースの概要をデータベースからフェッチして、それらをメモリに読み込む。
get_next_n()
destroy()

図 3-1 に、Basic University サンプル アプリケーションを示します。

図 3-1 Basic University サンプル アプリケーション

Basic University サンプル アプリケーション

Basic University サンプル アプリケーションで何が発生するかを説明するために、次のイベント グループについて説明します。

アプリケーションの起動

次に、Basic クライアント アプリケーションおよびサーバ アプリケーションが起動し、クライアント アプリケーションが Registrar オブジェクトのオブジェクト参照を取得するときに行われる一般的な一連のイベントを示します。

  1. Basic クライアント アプリケーションおよびサーバ アプリケーションが起動し、クライアント アプリケーションは FactoryFinder から RegistrarFactory オブジェクトのオブジェクト参照を取得します。
  2. RegistrarFactory オブジェクトの参照を使用して、クライアント アプリケーションは RegistrarFactory オブジェクトの find_registrar() オペレーションを呼び出します。
  3. RegistrarFactory はメモリ内に存在しません (このオブジェクトに対する要求が以前にサーバ プロセスに到着していないため)。このため、TP フレームワークは Server オブジェクトの Server::create_servant() オペレーションを呼び出して RegistrarFactory オブジェクトをインスタンス化します。
  4. インスタンス化が済んだら、RegistrarFactory オブジェクトの find_registrar() オペレーションが呼び出されます。RegistrarFactory オブジェクトは、Registrar のオブジェクト参照を作成してクライアント アプリケーションに返します。

コース概要の参照

次に、学生がコース概要のリストを参照するときに発生する一連のイベントを順番に示します。

  1. Registrar オブジェクトのオブジェクト参照を使用して、クライアント アプリケーションは get_courses_synopsis() オペレーションを呼び出し、次のものを指定します。
    • データベースからコース概要を検索するための検索文字列
    • 変数 number_to_get で表され、返される概要リストのサイズを指定する整数
  2. Registrar はメモリ内に存在しません (このオブジェクトに対する要求が以前にサーバ プロセスに到着していないため)。このため、TP フレームワークは Server オブジェクトに実装されている Server::create_servant() オペレーションを呼び出します。これにより、Registrar オブジェクトがサーバ マシンのメモリ内にインスタンス化されます。
  3. Registrar オブジェクトはクライアント要求を受信し、CourseSynopsisEnumerator オブジェクトのオブジェクト参照を作成します。CourseSynopsisEnumerator オブジェクトは、データベースからコース概要をフェッチするために Registrar オブジェクトによって呼び出されます。
  4. CourseSynopsisEnumerator オブジェクトのオブジェクト参照を作成するために、Registrar オブジェクトは次のことを行います。

    1. CourseSynopsisEnumerator オブジェクトのユニークな ID を生成します。
    2. CourseSynopsisEnumerator オブジェクトのオブジェクト ID を生成します。この ID は、前のステップで生成されたユニークの ID とクライアントによって指定された検索文字列を連結したものです。
    3. CourseSynopsisEnumerator オブジェクトのインタフェース リポジトリ ID をそのインタフェース タイプ コードから取得します。
    4. TP::create_object_reference() オペレーションを呼び出します。このオペレーションにより、最初のクライアント要求で必要な CourseSynopsisEnumerator オブジェクトのオブジェクト参照が作成されます。
  5. 前のステップで作成したオブジェクト参照を使用して、Registrar オブジェクトは CourseSynopsisEnumerator オブジェクトの get_next_n() オペレーションを呼び出して、リスト サイズを受け渡します。ステップ 1 で説明したとおり、このリスト サイズはパラメータ number_to_get によって表されます。
  6. TP フレームワークは、Server オブジェクトの Server::create_servant() オペレーションを呼び出して、CourseSynopsisEnumerator オブジェクトをインスタンス化します。
  7. TP フレームワークは、CourseSynopsisEnumerator オブジェクトの activate_object() オペレーションを呼び出します。このオペレーションは、次の 2 つのことを行います。
    • その OID から検索基準を抽出する。
    • その検索基準を使用して、一致するコース概要をデータベースからフェッチし、それらをサーバ マシンのメモリに読み込む。
  8. CourseSynopsisEnumerator オブジェクトは、Registrar オブジェクトに次の情報を返します。
    • 戻り値の CourseSynopsisList に指定されるコース概要リスト。これは、最初のコース概要リストを含む sequence です。
    • 検索基準に一致するが、まだ返されていないコース概要の数。これは、number_remaining パラメータによって指定されます。
  9. Registrar オブジェクトは、クライアント アプリケーションに CourseSynopsisEnumerator オブジェクト参照を返します。また、そのオブジェクトから取得した次の情報も返します。
    • 最初のコース概要リスト
    • number_remaining 変数
    • number_remaining 変数が 0 の場合、Registrar オブジェクトは CourseSynopsisEnumerator オブジェクトの destroy() オペレーションを呼び出し、クライアント アプリケーションに nil 参照を返します。

  10. クライアント アプリケーションは、一致する次の概要リストを取得するための要求を直接 CourseSynopsisEnumerator オブジェクトに送信します。
  11. CourseSynopsisEnumerator オブジェクトはそのクライアント要求を満たすと共に、更新した number_remaining 変数を返します。
  12. クライアント アプリケーションは、CourseSynopsisEnumerator オブジェクトとのやり取りを終了すると、CourseSynopsisEnumerator オブジェクトの destroy() オペレーションを呼び出します。この結果、CourseSynopsisEnumerator オブジェクトは TP::deactivateEnable() オペレーションを呼び出します。
  13. TP フレームワークは、CourseSynopsisEnumerator オブジェクトの deactivate_object() オペレーションを呼び出します。この結果、CourseSynopsisEnumerator オブジェクトが保持しているコース概要のリストがサーバ マシンのメモリから削除されます。これにより、CourseSynopsisEnumerator オブジェクトのサーバントを別のクライアント要求のために再利用できるようになります。

コース詳細の参照

次に、クライアント アプリケーションがコース詳細を参照するときに行われる一連のイベントを示します。

  1. 学生は、詳細を参照したいコースのコース番号を入力します。
  2. クライアント アプリケーションは、Registrar オブジェクトの get_course_details() オペレーションを呼び出し、コース番号のリストを受け渡します。
  3. Registrar オブジェクトは、一致するコース番号をデータベースから検索し、指定された各コースの詳細を含んだリストを返します。このリストは、CourseDetailsList 変数に格納されます。これは、コースの詳細を含んだ一連の struct です。

 


University サーバ アプリケーションの設計上の考慮事項

Basic University サンプル アプリケーションには、University サーバ アプリケーションが含まれます。このサーバ アプリケーションは、CORBA サーバ アプリケーションの基本的な設計問題を処理します。この節では、以下のトピックについて説明します。

この節では、さらに次の 2 つのトピックについても説明します。

オブジェクト参照の生成に関する設計上の考慮事項

Basic クライアント アプリケーションでは、University サーバ アプリケーションによって管理される次のオブジェクトの参照が必要です。

次の表に、これらの参照がどのように生成されて返されるかを示します。

オブジェクト
オブジェクト参照が
生成されて返されるしくみ
RegistrarFactory
RegistrarFactory オブジェクトのオブジェクト参照は Server オブジェクトで生成される。Server オブジェクトは、RegistrarFactory オブジェクトを FactoryFinder に登録する。クライアント アプリケーションは、RegistrarFactory オブジェクトの参照を FactoryFinder から取得する。
Basic University サーバ アプリケーション プロセスには、RegistrarFactory オブジェクトは 1 つしか存在しない。
Registrar
Registrar オブジェクトのオブジェクト参照は RegistrarFactory オブジェクトによって生成され、クライアント アプリケーションが find_registrar() オペレーションを呼び出したときに返される。Registrar オブジェクトに対して作成されるオブジェクト参照は常に同じです。このオブジェクト参照にはユニークな OID は含まれない。
Basic University サーバ アプリケーション プロセスには、Registrar オブジェクトは 1 つしか存在しない。
CourseSynopsisEnumerator
CourseSynopsisEnumerator オブジェクトのオブジェクト参照は、クライアント アプリケーションが get_courses_synopsis() オペレーションを呼び出したときに Registrar オブジェクトによって作成される。つまり、Registrar オブジェクトは CourseSynopsisEnumerator オブジェクトのファクトリである。CourseSynopsisEnumerator オブジェクトの設計と使い方については、この章で後述する。
Basic University サーバ アプリケーション プロセスには、任意の数の CourseSynopsisEnumerator オブジェクトが存在できる。

University サーバ アプリケーションがオブジェクト参照を生成する方法について、以下のことに注意してください。

オブジェクト状態の管理に関する設計上の考慮事項

Basic サンプル アプリケーションの 3 つのオブジェクトには、それぞれ独自の状態管理の要件が存在します。この節では、それぞれのオブジェクト状態管理の要件について説明します。

RegistrarFactory オブジェクト

RegistrarFactory オブジェクトは、特定のクライアント要求にユニークなものである必要はありません。また、このオブジェクトをメモリに保持しておき、クライアント呼び出しごとにこのオブジェクトをアクティブ化および非アクティブ化する負担を回避することは合理的です。したがって、RegistrarFactory オブジェクトには process アクティブ化ポリシーが割り当てられます。

Registrar オブジェクト

Basic サンプル アプリケーションは、小規模な環境へのデプロイに適しています。Registrar オブジェクトは、RegistrarFactory オブジェクトに似た特性を備えています。つまり、このオブジェクトは特定のクライアント要求にユニークなものである必要がありません。また、呼び出しごとにこのオブジェクトをアクティブ化および非アクティブ化する負担を回避することは合理的です。したがって、Basic サンプル アプリケーションでは、Registrar オブジェクトには process アクティブ化ポリシーが割り当てられます。

CourseSynopsisEnumerator オブジェクト

University サーバ アプリケーションの基本的な設計上の問題は、大きすぎて 1 回の応答ではクライアント アプリケーションに返すことができないコース概要リストをどのように処理するかです。したがって、この問題の解決策は、次のことが中心となります。

University サーバ アプリケーションは、この解決策を実装する CourseSynopsisEnumerator オブジェクトを備えています。このオブジェクトは最初に呼び出されたときに最初の概要リストを返しますが、その後もメモリ内コンテキストに保持されるので、クライアント アプリケーションは後続の要求で概要の残りを取得できます。メモリ内コンテキストを保持するには、CourseSynopsisEnumerator オブジェクトはステートフルでなければなりません。つまり、このオブジェクトは複数のクライアント呼び出しにわたってメモリ内に常駐します。

クライアントが CourseSynopsisEnumerator オブジェクトとの会話を終了するときに、このオブジェクトにはメモリからフラッシュされるための手段が必要です。このため、CourseSynopsisEnumerator オブジェクトの適切な状態管理の方法は、process アクティブ化ポリシーを割り当て、CORBA アプリケーション制御の非アクティブ化機能を実装することです。

アプリケーション制御の非アクティブ化は、そのオブジェクトの destroy() オペレーションによって実装されます。

次のサンプル コードに、CourseSynopsisEnumerator オブジェクトの destroy() オペレーションを示します。

void CourseSynopsisEnumerator_i::destroy()
{
        // クライアントが列挙子の「破棄」を呼び出すと、
        // このオブジェクトは「消滅」する必要がある。
        // そのためには、TP フレームワークに
        // このオブジェクトとの会話が完了したことを通知する

TP::deactivateEnable();
}

Basic University サンプル アプリケーションの ICF ファイル

次のサンプル コードに、Basic サンプル アプリケーション用の ICF ファイルを示します。

module POA_UniversityB
{
implementation CourseSynopsisEnumerator_i
{
activation_policy ( process );
transaction_policy ( optional );
implements ( UniversityB::CourseSynopsisEnumerator );
};
implementation Registrar_i
{
activation_policy ( process );
transaction_policy ( optional );
implements ( UniversityB::Registrar );
};
implementation RegistrarFactory_i
{
activation_policy ( process );
transaction_policy ( optional );
implements ( UniversityB::RegistrarFactory );
};
};

永続状態情報の処理に関する設計上の考慮事項

永続状態情報の処理とは、オブジェクトのアクティブ化中またはアクティブ化後のある時点でディスクから永続状態情報を読み取り、必要な場合、非アクティブ化中または非アクティブ化後のある時点でそれを書き込むことです。Basic サンプル アプリケーションでは、次の 2 つのオブジェクトが永続状態情報を処理します。

以降の 2 つの節では、この 2 つのオブジェクトが永続状態情報を処理する方法に関する設計上の考慮事項を説明します。

Registrar オブジェクト

Registrar オブジェクトのオペレーションの 1 つによって、クライアント アプリケーションにコース情報の詳細が返されます。一般的なシナリオでは、数多くのコース概要を参照した学生は、通常 2 つか 3 つのコースに関する詳細情報を一度に参照しようとします。

このシナリオを効率的に実装するために、Registrar オブジェクトには get_course_details() オペレーションが定義されています。このオペレーションは、コース番号のリストを指定するパラメータを入力として受け付けます。次にこのオペレーションは、データベースからコースの詳細を検索し、その詳細をクライアント アプリケーションに返します。このオペレーションが実装されるオブジェクトはプロセス バウンドなので、このオペレーションはその呼び出しの完了後に状態データをメモリに保持するのを避ける必要があります。

Registrar オブジェクトは、永続状態をメモリに保持しません。クライアント アプリケーションが get_course_details() オペレーションを呼び出すと、このオブジェクトは関連するコース情報を University データベースからフェッチしてクライアントに送信します。このオブジェクトは、コース データをメモリ内に保持しません。このオブジェクトの activate_object() オペレーションと deactivate_object() オペレーションでは永続状態は処理されません。

CourseSynopsisEnumerator オブジェクト

CourseSynopsisEnumerator オブジェクトは、自身が University データベースから検索するコース概要を処理します。状態処理に関する設計上の考慮事項は、ディスクから状態を読み取る方法です。このオブジェクトは、状態をディスクに書き込みません。

CourseSynopsisEnumerator オブジェクトの機能には、次の 3 つの重要な側面があります。これらの側面は、このオブジェクトがその永続状態を読み取る方法に影響を与えます。

この 3 つの側面を考えたとき、このオブジェクトでは次のことを行うのが合理的です。

したがって、CourseSynopsisEnumerator オブジェクトがアクティブ化されるときに、そのオブジェクトの activate_object() オペレーションは次のことを行います。

  1. その OID から検索基準を抽出します。
  2. 検索基準に一致するコース概要をデータベースから検索します。
注意 : オブジェクトの Tobj_ServantBase::activate_object() オペレーションまたは Tobj_ServantBase::deactivate_object() オペレーションを実装する場合は、実装ヘッダ ファイル (つまり、application_i.h ファイル) を編集し、これらのオペレーションの定義をそのオブジェクトのインタフェースのクラス定義テンプレートに追加してください。

University データベースの使い方

University サンプル アプリケーションが University データベースを使用する方法について、次のことに注意してください。

注意 : Wrapper および Production サンプル アプリケーションの Oracle Tuxedo Teller アプリケーションは、University データベース内の口座情報に直接アクセスし、samplesdb.h ファイルを使用しません。

Basic サーバ アプリケーションに組み込むファイルの詳細については、『Tuxedo CORBA University サンプル アプリケーション』を参照してください。

Basic サンプル アプリケーションがデザイン パターンを適用する方法

Basic サンプル アプリケーションは、次のデザイン パターンを使用します。

この節では、この 2 つのデザイン パターンが Basic サンプル アプリケーションに適している理由と、Basic サンプル アプリケーションがこれらのパターンを実装する方法について説明します。

Process-Entity デザイン パターン

Process-Entity デザイン パターン」で説明したように、このデザイン パターンは、クライアント アプリケーションによって必要とされるデータ エンティティを処理する 1 つのプロセス オブジェクトが存在する場合に適しています。データ エンティティは、クライアント アプリケーションではなくこのプロセス オブジェクトによって操作される CORBA struct としてカプセル化されます。

Process-Entity デザイン パターンを Basic サンプル アプリケーションに適用すると、Basic サンプル アプリケーションは細粒度オブジェクトの実装を回避できます。たとえば、Registrar オブジェクトは、同じような多数のコース オブジェクト セットの有効な代替となります。単一の粗粒度 Registrar オブジェクトを管理する負荷は、何百、何千もの細粒度のコース オブジェクトを管理する負荷に比べれば、それほど大きくはありません。

Process-Entity デザイン パターンの詳細については、デザイン パターンに関する技術情報を参照してください。

List-Enumerator デザイン パターン

このデザイン パターンは、大きすぎて 1 つの応答でクライアント アプリケーションに返すことができないデータの内部リストをオブジェクトが生成した場合に適しています。このため、オブジェクトは 1 回の応答で最初のデータ リストをクライアント アプリケーションに返し、後続の応答で残りのデータを返すことができなければなりません。

また、List-Enumerator オブジェクトは、既に返されたデータの量を同時に追跡して、後続のリストを正確に返すことができるようにする必要があります。List-Enumerator オブジェクトは常にステートフルであり (クライアント呼び出しにまたがってアクティブ化され、メモリに常駐する)、サーバ アプリケーションはそれらが不要になったときにそれらを非アクティブ化できます。

List-Enumerator デザイン パターンは、CourseSynopsisEnumerator オブジェクトに最適です。このデザイン パターンを実装すると、次のメリットが得られます。

Registrar オブジェクトは get_courses_synopsis() オペレーションを備えていますが、データベース クエリと概要リストの知識はすべて CourseSynopsisEnumerator オブジェクトに埋め込まれます。この場合、Registrar オブジェクトは単にクライアントが次のデータを取得するための手段として機能します。

Oracle Tuxedo システムに組み込まれた性能効率化

Oracle Tuxedo システムは、同じサーバ プロセス内の 2 つのオブジェクト間のデータ マーシャリングを自動的に無効化することによって、性能の効率化を実現します。この効率化は、次の環境が存在するときに得られます。

この例には、Registrar オブジェクトが CourseSynopsisEnumerator オブジェクトのオブジェクト参照を作成し、それによってそのオブジェクトがインスタンス化された場合などがあります。この 2 つのオブジェクト間の要求と応答では、データ マーシャリングは行われません。

状態を持つオブジェクトの事前アクティブ化

状態を持つオブジェクトの事前アクティブ化機能を使用すると、クライアント アプリケーションがオブジェクトを呼び出す前にそのオブジェクトをアクティブ化できます。この機能は、University サンプルの CourseSynopsisEnumerator オブジェクトなどのイテレータ オブジェクトを作成するときに特に役立ちます。

状態を持つオブジェクトの事前アクティブ化では、TP::create_active_object_reference() オペレーションを使用します。通常、クライアントがあるオブジェクトに対する呼び出しを発行するまで、CORBA サーバ アプリケーションでそのオブジェクトは作成されません。ただし、オブジェクトを事前アクティブ化し、TP::create_active_object_reference() オペレーションを使用してそのオブジェクトの参照をクライアントに受け渡すことによって、クライアント アプリケーションは既にアクティブ化され、状態を持っているオブジェクトを呼び出すことができます。

注意 : 状態を持つオブジェクトの事前アクティブ化の機能は、WebLogic Enterprise バージョン 4.2 で最初に導入されました。

状態を持つオブジェクトを事前アクティブ化する方法

事前アクティブ化の機能を使用するためのプロセスは、サーバ アプリケーションに次のコードを記述することです。

  1. オブジェクトを作成するための C++ new 文の呼び出しを含めます。
  2. オブジェクトの状態を設定します。
  3. TP::create_active_object_reference() オペレーションを呼び出して、新しく作成されたオブジェクトの参照を取得します。このオブジェクト参照は、クライアント アプリケーションに返すことができます。

このように、事前アクティブ化オブジェクトは、TP フレームワークがそのオブジェクトの Server::create_servant() オペレーションと Tobj_ServantBase::activate_object() オペレーションを呼び出さずに作成されます。

事前アクティブ化オブジェクトの使い方に関する注意

事前アクティブ化機能を使用するときには、以下のことに注意してください。


  ページの先頭       前  次