コンテンツにスキップ

1. はじめての Process

最初の章では、引数に 1 を足して返すだけの Process を動かします。 書いたコードは短い関数ひとつですが、juiz はそれを読み込んで、ネットワーク越しに呼び出せる部品にしてくれます。

サンプル集をクローンしてビルドします。以降のコマンドは、すべてクローンしたリポジトリのルートで実行します。

ターミナルウィンドウ
git clone https://github.com/OpenJUIZ/juiz_examples_rust.git
cd juiz_examples_rust
cargo build

各サンプルは共有ライブラリとして target/debug にビルドされます。

引数 arg1 に 1 を足して返す Process です。

process/increment_process/src/lib.rs

use juiz_sdk::prelude::*;
#[juiz_process]
fn increment_process(arg1: i64) -> JuizResult<Capsule> {
log::trace!("increment_process({:?}) called", arg1);
return Ok(jvalue!(arg1 + 1).into());
}

#[juiz_process] を付けた関数が Process になります。関数名 increment_process が Process の型名、引数名 arg1 がそのまま引数の名前になります。 戻り値は jvalue! で値を作り、Capsule に変換して返します。

このクレートは Cargo.toml で共有ライブラリ(crate-type = ["cdylib"])としてビルドする設定になっています。

どの言語でも、Process は「引数を受け取って結果を返すだけ」の関数です。 外部の状態を読み書きしないので、同じ引数を渡せばいつも同じ結果が返ります(冪等)。 この性質のおかげで、Process はテストしやすく、あとでつないだり別のマシンに置いたりしても振る舞いが変わりません。

--process でファイルを指定して juiz を起動します。

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

macOS では拡張子が .dylib になります(./target/debug/libincrement_process.dylib)。

オプションの意味は次のとおりです。

オプション 意味
--process <パス> Process のファイルを読み込む
-l <言語> ファイルの言語(rust / python / cpp、既定は rust)
-1 読み込んだ Process から、インスタンスを 1 つ作る
-e 作ったインスタンスを、既定の引数で 1 回実行する
-d HTTP ブローカーを 8000 番ポートで立ち上げて待機する(Ctrl+C で終了)

ここで「読み込む」と「インスタンスを作る」が分かれていることに注目してください。 ファイルを読み込むと、juiz は Process の型(作り方)を覚えます。-1 を付けると、その型からインスタンスを 1 つ作ります。 インスタンス名は、型名の後ろに 0 を付けた名前(increment_process0 など)になります。 同じ型から、名前の違うインスタンスをいくつも作ることもできます(第 3 章で扱います)。

juiz を起動したまま、別のターミナルを開いて Process を呼び出してみます。 まず、動いている Process の一覧を見ます。

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

表示された URL が、この Process の ID です。 http://127.0.0.1:8000 は Process がいる場所(ブローカー)、process/ の後ろは「インスタンス名::型名」を表しています。

この ID と引数を指定して、Process を呼び出します(call)。引数は JSON で渡します。

ターミナルウィンドウ
juiz process call "http://127.0.0.1:8000/process/increment_process0::increment_process" '{"arg1": 3}' -p
# => CapsulePtr((value:Value(4), option: []))

3 を渡して 4 が返ってきました。-p は結果を表示するオプションです。 何度呼び出しても、同じ引数なら同じ結果が返ることも確かめてみてください。

-d で立ち上げた HTTP ブローカーは、Swagger UI も提供しています。ブラウザで次の URL を開きます。

http://127.0.0.1:8000/docs/

一覧から PATCH /api/process/call を開き、「Try it out」を押して次のように入力し、「Execute」を押すと結果が返ってきます。

  • identifier: core://core/process/increment_process0::increment_process
  • Request body: {"arg1": 3}

juiz コマンドも Swagger UI も、HTTP で同じ API を呼んでいるだけです。 つまり、HTTP を話せるプログラムなら、どの言語からでも Process を呼び出して結果を受け取れます。 これが、juiz をサーバー・クライアントのように使う call という使い方です。

Process の中身を変えて、もう一度動かしてみましょう。 たとえば 1 を足す代わりに 2 倍にして返すように書き換え、ビルドし直して(Python はそのまま)juiz を起動し直すと、{"arg1": 3} に対して 6 が返ってくるはずです。

1 を引く Process(decrement_process)もサンプル集に入っています。同じ手順で動かせます。

  • Process は、引数を受け取って結果を返すだけの冪等な関数です。Rust・Python・C++ のどれでも書けます。
  • juiz はファイルを読み込んで Process の型を覚え、そこから名前の付いたインスタンスを作ります。
  • 動いている Process には URL の形をした ID があり、ID と引数を指定して外から呼び出せます(call)。

次の章では、カウンタを題材にして、状態を持つ部品の書き方を学びます。状態を持つ: Container と ContainerProcess に進みましょう。