Lambda Prelude は常駐バックエンドサービス向け。デプロイの基本方針は、単一ネイティブバイナリを生成し、それを Linux の init システム / コンテナ / オーケストレータで動かすことにある。

ビルド

lambda-prelude build src/main.lp --out my-service

出力は ocamlopt がリンクした本物のネイティブバイナリ。実行時にインタプリタは不要。レシーバを型検査器が特定できる送信は直接 OCaml 呼び出しに落ち、それ以外はバイナリが link するランタイムディスパッチャを通る。

クロスプラットフォーム

機能が完成扱いとなる前に両ターゲットを通す。片方でしか動かない変更は未完成扱い。

プラグイン読み込み

PostgreSQL / MariaDB / MySQL / Redis / Valkey のバインディングは、インタプリタでも AOT バイナリでも OCaml の Dynlink 経由で読み込まれる。プラグインファイル (.cmxs) は次の順で検索し、最初に見つかったものを使う。

  1. $LAMBDA_PRELUDE_PLUGINS が設定されていればその 1 ディレクトリ (override)
  2. ワーキングディレクトリ直下の ./plugins/
  3. 実行中バイナリ横の <exe_dir>/plugins/ (インストール配置)
  4. <exe_dir>/../plugins/ (Linux パッケージ配置)
  5. _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-service

init 統合

バイナリは普通の常駐プロセス。ホスト OS へは他のデーモンと同じように繋ぎ込む。

随伴 VM もアップロードするランタイムイメージも JIT ウォームアップ窓もない。

クラッシュ復旧

バイナリ内部ではアクターレベルの失敗をスーパーバイザツリーが捌く。バイナリ間ではプロセスレベルの失敗をホスト OS の再起動ポリシーが捌く。

スーパーバイザツリーを内層 (ミリ秒オーダーのプロセス内再起動)、OS init を外層 (秒オーダーのプロセス再起動) と見なす。Erlang の supervisorheart の分担と同じ分け方。