[openrtm-users 01099] Re: Managerのnamingformatの不具合
Ando Noriaki
n-ando @ aist.go.jp
2010年 2月 15日 (月) 12:43:08 JST
菅様、皆さま
安藤です
rtcdについて、まだドキュメントを書いていないので、
いろいろ混乱させてしまいすみません。
ドキュメントはもう少々お待ちください。
今回の件ですが、ネームサーバ上に残ったマネージャーのゾンビリファレンスが、
そのごrtc.confでマネージャの登録名を変えたにもかかわらず復活してしまう
ということでよろしいでしょうか。
これは、簡潔に言いますと、マネージャーを INS 化したためで、
対処方法としては、ゾンビ化させないで、マネージャはshutdownコマンドで
終了させてください、ということになります。
以下、長文すみません。
> さて,今回の問題ですが,追加報告です.
> rtcdを使って現象をいくつか試していますが,
> 以下の操作で再現されることがわかりました.
>
> 一言で表現すると,ゾンビーの復活です.
>
> 初回のrtcdの実行ではnaming_formatsを指定しない,
> 以下のrtc.confで実行.
>
> corba.nameservers: localhost
> naming.formats: %h.host_cxt/%n.rtc
> logger.enable: NO
> logger.log_level: PARANOID
> manager.modules.load_path: ../examples/C++/, ../components/
>
> その後,rtcdを無理やり停止して,ゾンビーを残す.
>
> 次にrtc.confを加工する
>
> corba.nameservers: localhost
> naming.formats: %h.host_cxt/%n.rtc
> logger.enable: NO
> logger.log_level: PARANOID
> manager.naming_formats: %h.host_cxt/ysuga_net.app_cxt/%n.mgr
> manager.modules.load_path: ../examples/C++/, ../components/
>
> 5行目を追加.そして実行すると,
> ゾンビーだったmanager.mgrが復活する.
> こちらからcreateを呼び出しても可能になってしまいます.
>
> 初回の起動でゾンビーがなければ意図通りに動作します.
> また,逆の順序で実行しても同様の現象が起こります.
詳しく解説しますと、
CORBAオブジェクトは、特に何もしていしなければ、生成されるたびに適当なKey (IDのようなもの)
を持ったオブジェクトとして生成され、ネームサーバに登録されるリファレンスも、
たとえ名前が同じであっても、生成されるたびに異なるKeyのオブジェクトとして
登録されます。
たとえば、ConsoleIn コンポーネントを2回生成したとします。
1回目の生成では、以下のような参照がネームサーバに登録されます。
名前: ConsoleIn0.rtc 参照:(Key: 0x7183618368, IPアドレス: 192.168.1.10, ポート番号:3444)
このプロセスを落として、もう一度起動します。次は、以下のような参照が登録されます。
名前: ConsoleIn0.rtc 参照:(Key: 0x8297427492, IPアドレス: 192.168.1.10, ポート番号:3653)
通常、複数回起動しても同じなのはIPアドレスと名前くらいで、Keyやポート番号はORBやOS
の気分によって変わってしまいます(笑
しかし、rtcdを-dオプション付きで起動すると、マネージャーはマスターマネージャ(後ほど解説します)となり、
のKeyとポート番号が固定されます。(デフォルトでは Key は manager, ポート番号は 2810 になります。)
つまり、マネージャーの名前は、以下のような参照としてネームサーバに登録されます。
名前: hsotname.host_cxt/manager.mgr 参照:(Key: manager, IPアドレス:
192.168.1.10, ポート番号:2810) ・・・ (1)
ここで、マネージャーを強制終了すると、この名前の登録を掃除しないで終了するので、
ネームサーバ上にこの名前がそのまま残ってしまいます。
次に、rtc.confでmanager.naming_formats を変更すると、
名前: hostname.host_cxt/ysuga_net.app_cxt/manager.mgr 参照:(Key: manager,
IPアドレス: 192.168.1.10, ポート番号:2810) ・・・ (2)
として、マネージャが登録されます。
ここで、(1)と(2)の参照(ID、IP、ポート)を比べてみると、まったく同じになっています。
したがって、(1)の参照にアクセスしても、(2)と同じオブジェクトにアクセスすることになります。
そういうわけで、ゾンビ化したマネージャ(1)も、復活してしまう、というわけです。
なお、マネージャをこのようにIDやポート番号を固定したわけは、ネームサーバなして
マネージャやコンポーネントにアクセスするためです。この辺は、以前松坂さんからご意見のあった、
ネームサーバがシステムの single point of failure になることを避ける手段として
ネームサーバに依存しないでシステムを構築する方法を提供したかったためです。
こうすることでマネージャは corbaloc:iiop:hostname:port/manager という URL で常に
アクセスできるようになります。ここでポート番号は固定で 2810 としているので、
ホスト名さえ分かれば、そのノードのマスタマネージャにアクセスできることになります。
ちなみに、こういうオブジェクトの名前付けを INS (Interoperable Naming Service) といいます。
以下は、log出力の例ですが、マネージャのIOR(オブジェクト参照)の情報は、
Feb 15 10:35:40 DEBUG: ManagerServant: Manager's IOR information:
IOR information
Type ID: "IDL:RTM/Manager:1.0"
Profiles:
1. IIOP 1.2 192.168.100.2 2810
Object Key: "manager" = 0x6d616e61676572 (7 bytes)
TAG_ORB_TYPE omniORB
TAG_CODE_SETS char native code set: ISO-8859-1
char conversion code set: UTF-8
wchar native code set: UTF-16
wchar conversion code set: UTF-16
このように、Object Key が "manager" という人間が読める形式になっているのに対し、
以下は ConsoleIn をネームサーバに登録する際のIORなのですが、
IOR information
Type ID: "IDL:openrtm.aist.go.jp/OpenRTM/DataFlowComponent:1.0"
Profiles:
1. IIOP 1.2 192.168.100.2 2810
POA(root) Object Key: "...." = 0x00000000 (4 bytes)
Object Key: "...xK........." = 0xfe94ba784b000015080000000000 (14 bytes)
TAG_ORB_TYPE omniORB
TAG_CODE_SETS char native code set: ISO-8859-1
char conversion code set: UTF-8
wchar native code set: UTF-16
wchar conversion code set: UTF-16
Object Key が 0xfe94ba784b000015080000000000 というORB (というかPOA) が
適当に付けた名前になっています。
ついでですので、マネージャの使い方についても少し説明します。
マネージャにはマスタとスレーブがあります。
・マスタマネージャ:
原則1ノードにつき1つだけ存在する。
アプリケーション、ノードの外部などからは、マスターマネージャに対して
コンポーネントの生成を依頼する。
つまり、原則として、このマネージャ自身はコンポーネントを生成・管理しない。
実際のコンポーネントの生成は、マスタがスレーブマネージャに依頼する。
・スレーブマネージャ:
1ノードに複数存在できる。0個以上のマスターに所属することができる。
rtcdを-dなしで起動した場合、マスターがすでに起動していればその配下に入る。
コンポーネントはスレーブマネージャ上で生成・管理される。
原則、コンポーネントが存在しないスレーブマネージャは存在しない(自動でシャットダウンされる)。
-> 菅さんがご指摘されたように、-d オプションなしのrtcdが自動で終了するのはこのためです。
マスターマネージャからは、スレーブはポート番号で区別される。
つまり、同一ポート番号のスレーブマネージャは、同一のプロセス(逆もしかり)である。
コンポーネント生成の流れは、以下のようになります。
1) RTCが起動される可能性のあるノード上では、rtcd は -d オプション付きで起動されているものとします。
#Linuxではれば、/etc/init.d 以下の起動スクリプトなどで起動されているイメージ。
2) 何らかのツール、コマンド、アプリケーションが、あるノードに対してコンポーネントを作成したい場合
まず、そのノードのマスタマネージャのオブジェクトリファレンスを取得します。
それは、ネームサーバからでもいいですし、corbaloc:iiop:hostname:2810/manager という URL を
ORB::string_to_object() 関数を使ってダイレクトにアクセスしてもかまいません。
3) 何らかのツール、コマンド、アプリケーションが、あるノード上で、コンポーネントを起動する場合、
そのノードのマスターマネージャに対して create_component() をコールします。
mgr->create_component("ConsoleIn?manager=localhost:2811&instance_name=ConsoleIn1234")
4) manager=localhost:2811 はローカルホスト上の 2811版ポート上で ConsoleIn という
コンポーネントを起動しなさい、という意味なので、マスターマネージャは、スレーブマネージャを
2811ポート上で起動し、そのマネージャに対して、create_component("ConsoleIn?instance_name=ConsoleIn1234")
をコールします。
5) スレーブマネージャは、ポート2811上で起動し、ConsoleInを一つ生成します。
このとき、インスタンス名はConsoleIn1234 に指定されているのでインスタンス名はこの名前になり、
ネームサーバ上に登録される名前も、この名前になります。
6) さらに、同じプロセス上で、ConsoleIn を起動したければ、
mgr->create_component("ConsoleIn?manager=localhost:2811&instance_name=ConsoleIn1235")
とをマスタマネージャに対してコールすればよく、異なるプロセスで起動したい場合は、
mgr->create_component("ConsoleIn?manager=localhost:2812&instance_name=ConsoleIn1235")
等とすれば、別のプロセス上でConsoleInが起動します。
7) なお、そのノード上で起動しているコンポーネントの参照は、マスターマネージャから、
mgr->get_components() によって取得できます。
スレーブ上で起動しているすべてのコンポーネントの参照をマスターが収集して返しています。
一応、1.0-RELEASEのrtcdはこのような使い方を意図して実装されています。
まだ、ツールの方でも対応しきれていないので、この使い方が実際利用できるのには
少々時間がかかると思いますが、RTSystemEditorやrtcshellなどで、
簡単にできるようにしていきたいと思います。
#rtcshellについては、ジェフさんよろしく。
あと、Windows上で起動したrtcdに、RTSystemEditorのmanager viewからアクセスすると、
非常に重いのですが、これはDLLからRTCのプロファイルを取得する操作がWindows
上ではなぜだか非常に遅いために発生しています。(Linuxだと一瞬で終わるのですが。。。)
また、OpenCVをインストールしていない場合、RTCのプロファイルを取得する過程で、
USBcamera*コンポーネントをアクセスした段階で、DLLのエラーダイアログが出てしまい
アクセスがさらに遅くなってしまいます。
OpenCVをインストールするか、USBCameda*.DLLを削除するかすると改善します。
--
安藤慶昭@独立行政法人産業技術総合研究所 知能システム研究部門
統合知能研究グループ 主任研究員, 博士(工学)
〒305-8568 つくば市梅園1-1-1 中央第2
e-mail: n-ando @ aist.go.jp, web: http://staff.aist.go.jp/n-ando
OpenRTM-aist: http://www.openrtm.org
openrtm-users メーリングリストの案内