CORBAサーバー・アプリケーションの作成

     前  次    新規ウィンドウで目次を開く  新規ウィンドウで索引を開く  PDFとして表示 - 新規ウィンドウ  Adobe Readerを取得 - 新規ウィンドウ
コンテンツはここから始まります

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オブジェクトは、一致するコース番号をデータベースから検索し、指定された各コースの詳細を含んだリストを戻します。このリストは、コース全体の詳細を含んだ一連のstructであるCourseDetailsList変数に格納されます。

 


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

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

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

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

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

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

オブジェクト
オブジェクト参照が
生成されて返されるしくみ
RegistrarFactory
RegistrarFactoryオブジェクトのオブジェクト参照は、RegistrarFactoryオブジェクトをFactoryFinderに登録するServerオブジェクトで生成されます。クライアント・アプリケーションは、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()
{
// When the client calls "destroy" on the enumerator,
// then this object needs to be "destructed".
// Do this by telling the TP framework that we're
// done with this object.

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サーバー・アプリケーションに組み込むファイルの詳細は、『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()操作を呼び出さずに作成されます。

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

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


  先頭に戻る       前  次