Lambda Prelude は常駐バックエンドサービス向け。デプロイの基本方針は、単一ネイティブバイナリを生成し、それを Linux の init システム / コンテナ / オーケストレータで動かすことにある。
ビルド
lambda-prelude build src/main.lp --out my-service
出力は ocamlopt がリンクした本物のネイティブバイナリ。実行時にインタプリタは不要。レシーバを型検査器が特定できる送信は直接 OCaml 呼び出しに落ち、それ以外はバイナリが link するランタイムディスパッチャを通る。
クロスプラットフォーム
- Windows — MinGW-w64 リンクバイナリ、実行時 Cygwin DLL 非依存。第一級の開発環境。
- Linux — 標準 ELF バイナリ、第一級の本番デプロイ先。
機能が完成扱いとなる前に両ターゲットを通す。片方でしか動かない変更は未完成扱い。
プラグイン読み込み
PostgreSQL / MariaDB / MySQL / Redis / Valkey のバインディングは、インタプリタでも AOT バイナリでも OCaml の Dynlink 経由で読み込まれる。プラグインファイル (.cmxs) は次の順で検索し、最初に見つかったものを使う。
$LAMBDA_PRELUDE_PLUGINSが設定されていればその 1 ディレクトリ (override)- ワーキングディレクトリ直下の
./plugins/ - 実行中バイナリ横の
<exe_dir>/plugins/(インストール配置) <exe_dir>/../plugins/(Linux パッケージ配置)_build/default/plugins/(開発ワークフロー)
AOT バイナリには同じランタイムが一緒にコンパイルされているので、これらのプラグインを同一に読み込む — ビルドによって失われるプラグイン機能はない。TORM は標準ライブラリに同梱され、どのバックエンドでも動く。必要なのは対応するプラグインを実行時の検索パス上に置くことだけ。
サービスレイアウト
小規模サービスの典型構成は次のとおり。
my-service/
main.lp
config.lp
service/
XA001Save.lp
XA001GetAll.lp
tests/
save_test.lp
getall_test.lp
lambda-prelude new my-service がエントリポイントとテストディレクトリを生成する。
lambda-prelude new my-service
cd my-service
lambda-prelude run main.lp
lambda-prelude test tests
lambda-prelude build main.lp --out my-serviceinit 統合
バイナリは普通の常駐プロセス。ホスト OS へは他のデーモンと同じように繋ぎ込む。
- systemd —
ExecStart=を 1 行書いた unit、Restart=on-failure、非特権サービスアカウント用にUser= - Docker —
FROM debian:stable-slimで十分。バイナリを COPY して実行 - Kubernetes — 標準の
Deployment+Service。/healthzを出すなら readiness probe を当てる
随伴 VM もアップロードするランタイムイメージも JIT ウォームアップ窓もない。
クラッシュ復旧
バイナリ内部ではアクターレベルの失敗をスーパーバイザツリーが捌く。バイナリ間ではプロセスレベルの失敗をホスト OS の再起動ポリシーが捌く。
スーパーバイザツリーを内層 (ミリ秒オーダーのプロセス内再起動)、OS init を外層 (秒オーダーのプロセス再起動) と見なす。Erlang の supervisor と heart の分担と同じ分け方。