コンテンツにスキップ

6. 別々のプロセスをつなぐ

第 4 章では、talker と listener を 1 つの設定ファイルに書いて、1 つの juiz の中でつなぎました。 ロボットでは、カメラを動かすプログラムと、画像を処理するプログラムを別々に起動したり、別々のコンピュータで動かしたりすることがよくあります。 この章では、talker と listener を別々のターミナルの juiz で起動し、動いている最中にコマンドからつなぎます。

第 4 章と同じ talker と listener を使います。サンプル集は、第 1 章でクローンしてビルドしたものをそのまま使えます。 まだの場合は、第 1 章の「サンプルを用意する」 の手順を済ませてください。

この章ではターミナルを 3 つ使います。どれも、サンプル集のルートで開いておいてください(Python の場合は、どのターミナルでも venv を有効にしておきます)。

ターミナル 役割
1 listener を動かす juiz
2 talker を動かす juiz
3 つないだり呼び出したりするコマンドを打つ

ターミナル 1 で、listener を読み込んだ juiz を起動します。第 1 章と同じく、-1 でインスタンスを 1 つ作り、-d でサーバーとして動かし続けます。

ターミナルウィンドウ
juiz --process ./target/debug/liblistener.so -1 -d

macOS では拡張子が .dylib になります。

起動しても何も表示されません。listener を実行する人がまだいないからです。 ターミナル 3 から、listener の ID を確かめておきましょう。

ターミナルウィンドウ
juiz process list
# => ["http://127.0.0.1:8000/process/listener0::listener"]

この juiz は、HTTP ブローカーのポート 8000 番で待ち受けています。

ターミナル 2 で、talker を読み込んだ juiz を起動します。今度は -r 1.0 を付けます。

ターミナルウィンドウ
juiz --process ./target/debug/libtalker.so -1 -r 1.0 -d

-r は、起動時に作ったインスタンスを、指定した周期 [Hz] で実行し続けるオプションです。ターミナル 2 には talker の表示だけが 1 秒ごとに出ます。

talker: Hello World
talker: Hello World
...

8000 番はターミナル 1 の juiz が使っているので、2 つ目の juiz は自動的に次の 8001 番で待ち受けます。 このとき 2 つ目の juiz は、8000 番の juiz に「8001 番にいる」と知らせ、そのサブシステムとして登録されます。 そのため、ターミナル 3 から 8000 番に問い合わせると、両方の juiz の Process が一覧に出てきます(並び順は実行ごとに変わることがあります)。

ターミナルウィンドウ
juiz process list
# => ["http://127.0.0.1:8000/process/listener0::listener", "http://127.0.0.1:8001/process/talker0::talker"]

ID の http://127.0.0.1:8000 や http://127.0.0.1:8001 の部分が、その Process がどの juiz にいるかを表しています。 特定の juiz だけに問い合わせたいときは、-s で問い合わせ先を指定します(指定しないと http://127.0.0.1:8000 に問い合わせます)。たとえば juiz -s http://127.0.0.1:8001 process list なら、talker だけが返ります。

ターミナル 3 で、talker の出力を listener の引数 arg1 につなぎます。

ターミナルウィンドウ
juiz connection create -t push \
"http://127.0.0.1:8001/process/talker0::talker" \
arg1 \
"http://127.0.0.1:8000/process/listener0::listener"

引数は、つなぐ元(source)の ID、つなぐ先の引数名(arg_name)、つなぐ先(destination)の ID の順です。-t push は、第 4 章の connection_type: Push と同じ意味です。 第 4 章の設定ファイルの connections に書いた内容を、そのままコマンドで指定していることがわかります。

実行したとたん、ターミナル 1 の listener が表示を始めます。

listener: Hello World
listener: Hello World
...

別々に起動した juiz の Process が、動いたままつながりました。つながりは、値を送り出す talker の側が持っています。8001 番に問い合わせると確かめられます。

ターミナルウィンドウ
juiz -s http://127.0.0.1:8001 connection list
# => [ConnectionID(src=ProcessIdentifier(core://core/process/talker0::talker, arg=arg1, dst=ProcessIdentifier(http://127.0.0.1:8000/process/listener0::listener)]

つなぐ先が http://127.0.0.1:8000/... になっています。talker の juiz は、listener が別の juiz にいることを知っていて、HTTP で値を届けています。 Process のコードは第 4 章から何も変えていません。同じ juiz の中にいても、別の juiz にいても、ID さえわかればつなげます。

call も、ID を指定すればどの juiz の Process にでも使えます。ターミナル 3 から、8001 番の juiz にいる talker を呼び出してみましょう。

ターミナルウィンドウ
juiz process call "http://127.0.0.1:8001/process/talker0::talker" '{}' -p
# => CapsulePtr((value:Value("Hello World"), option: []))

process call は、ID の http://127.0.0.1:8001 を見て、その juiz に問い合わせます。このように ID を指定するコマンドには -s は要りません。

-r は、起動時に作ったインスタンスを手軽に周期実行するためのオプションで、Execution Context(EC)は作りません。 第 4 章のように EC で動かしたいときは、設定ファイルで EC を作ります。ここでは、EC を止めた状態で起動しておき、あとから外から開始・停止してみます。

まず、ターミナル 2 の talker を Ctrl+C で止めます。listener の表示も止まります。 次に、talker と EC だけを書いた設定ファイル talker_ec.conf を、サンプル集のルートに作ります。第 4 章の talker_listener.conf から listener と connections を除き、auto_start を false にしたものです。

name: talker_ec
option:
http_broker:
start: true
port: 8000
plugins:
process_factories:
talker:
path: "./target/debug"
processes:
- type_name: talker
name: talker0
ecs:
- name: ec0
type_name: main_loop_ec
rate: 1.0
bind:
- name: talker0
type_name: talker
auto_start: false

ターミナル 2 で、この設定ファイルを使って起動し直します。port: 8000 と書いてありますが、8000 番は listener の juiz が使っているので、やはり 8001 番で待ち受けます。

ターミナルウィンドウ
juiz -f talker_ec.conf -d

EC が止まっているので、何も表示されません。 talker を起動し直したので、つながりも消えています(つながりは talker の側が持っていたからです)。ターミナル 3 から、もう一度つなぎます。インスタンス名が talker0 になっていることに注意してください。

ターミナルウィンドウ
juiz connection create -t push \
"http://127.0.0.1:8001/process/talker0::talker" \
arg1 \
"http://127.0.0.1:8000/process/listener0::listener"

つないでも、まだ何も流れません。EC が talker を実行していないからです。8001 番の juiz にある EC の ID を調べます。

ターミナルウィンドウ
juiz -s http://127.0.0.1:8001 ec list
# => ["http://127.0.0.1:8001/execution_context/ec0::main_loop_ec"]

この ID を指定して、EC を開始します。

ターミナルウィンドウ
juiz -s http://127.0.0.1:8001 ec start "http://127.0.0.1:8001/execution_context/ec0::main_loop_ec"

ターミナル 2 に talker、ターミナル 1 に listener の表示が 1 秒ごとに出始めます。止めるときは ec stop です。

ターミナルウィンドウ
juiz -s http://127.0.0.1:8001 ec stop "http://127.0.0.1:8001/execution_context/ec0::main_loop_ec"

表示が止まります。もう一度 ec start すれば、また動き出します。

  • talker の -r を 2.0 にして起動し直し、もう一度つないでみましょう。listener の表示の間隔が半分になります。
  • 起動する順番を入れ替えて、talker を先(8000 番)、listener を後(8001 番)に起動してみましょう。つなぐときの ID のポート番号が入れ替わるだけで、同じようにつなげます。
  • talker_ec.conf の rate を変えたり、auto_start を true にしたりして、EC の動き方の違いを確かめてみましょう。
  • 別々に起動した juiz の Process も、http://<ホスト>:<ポート>/process/<インスタンス名>::<型名> という ID で指定できます。2 つ目以降の juiz は、空いているポート(8001, 8002, …)で待ち受けます。
  • juiz connection create で、動いている Process どうしを、設定ファイルなしでつなげます。つながりは値を送り出す側の Process が持っています。
  • juiz process call は、ID が指す juiz に問い合わせて結果を受け取ります。
  • -r は手軽に周期実行するためのオプションです。EC を使うときは設定ファイルで作り、juiz ec start / juiz ec stop で外から開始・停止できます。
  • Process のコードは、どこで動くのか、誰とつながるのかを知りません。だから同じ Process を、1 つの juiz の中でも、別々の juiz の間でも使えます。

次の章では、この章の HTTP ブローカーの代わりに QUIC ブローカーを使って、同じように別々の juiz をつなぎます。通信方式を選ぶ: QUIC ブローカー に進みましょう。