はじめに
Livebook Launch Week 2 を自分でやってみるシリーズ
- Day1: Smart Cell からのリモート接続 <- ここ
- Day2: Whisper による音声認識の新機能
- Day3: ファイルをドラッグ&ドロップすると、扱うためのコードを自動生成する
- Day4:
- Day5: Vim と Emacs のキーバインド
Day 1 は Smart Cell からのリモート接続です
今までもリモートノードに接続できていましたが、 Smart Cell からの実行では「自由に Kino などを使った視覚化ができる」のが特徴です
本記事では Attached node によるリモート接続と、 Smart Cell によるリモート接続を両方実行し、比較します
Phoenix の準備
以下のコマンドで Phoenix プロジェクトを新規作成します
今回は DB を使わないため --no-ecto
を指定しています
mix phx.new phoenix_sample --no-ecto
Fetch and install dependencies? [Yn]
と訊かれるので、そのまま Enter を押して依存モジュールをインストールしましょう
作成された Phoenix プロジェクトのディレクトリーに移動します
code phoenix_sample
ノード名とクッキーを指定して Phoenix を起動します
iex --sname phoenix_sample --cookie mycookie -S mix phx.server
ブラウザで http://localhost:4000/ を開くと Phoenix の初期画面が表示されます
Livebook の準備
今回はローカルで Livebook を起動します
Livebook の README にある通り、 Elixir と Erlang のある環境下でコマンドを実行します
git clone https://github.com/livebook-dev/livebook.git
cd livebook
mix deps.get --only prod
MIX_ENV=prod mix phx.server
ブラウザで http://localhost:8080/ を開くと Livebook のホーム画面が表示されます
Attached node によるリモート接続
Livebook のホーム画面から右上の + New notebook をクリックし、新しいノートブックを開きます
Livebook の左メニュー CPU アイコンをクリックし、 RUNTIME メニューを開きます
RUNTIME メニューの Type が ELixir standalone になっており、ノードに接続されていないことが分かります
RUNTIME メニューの上部 RUNTIME という文字の右側にある歯車アイコンをクリックします
Runtime settings ノードが開くので、 Attached node をクリックします
Name と Cookie に Phoenix 起動時に指定したノード名、クッキーを入力し、 Connect をクリックします
これによって、作成した Phoenix プロジェクトに接続されます
モーダルを閉じると RUNTIME メニューの Type が Attached になっています
この状態でセットアップセルの右上、モジュール追加のアイコンにマウスカーソルを合わせると、 The current runtime does not support adding dependencies
とツールチップが表示されます
本来、ノートブックは Kino などのモジュールを追加することでデータを視覚化できるのですが、 Attached node の状態では接続先ノードの中で動いているため、 モジュールを追加できなくなっています
セルに Pho
と入力すると、補完候補に PhoenixSample
や PhoenixSampleWeb
が表示され、確かにリモート接続できている(リモートの情報が取得できている)ことが分かります
セルに以下のコードを入力し、実行します
PhoenixSampleWeb.Endpoint.server_info(:http)
実行結果
{:ok, {{127, 0, 0, 1}, 4000}}
リモートノードが IP アドレス 127.0.01 の 4000 番ポートで起動していることが分かります
次のセルに以下のコードを入力して実行します
Range.new(1, 10)
|> Enum.map(fn _ ->
Process.sleep(1000)
:erlang.memory(:total)
end)
実行結果
[64342032, 64412112, 64449024, 64496960, 64387800, 64674576, 64716656, 64669320, 64711400, 64632640]
1秒間隔で Phoenix のメモリ使用量が取得できました
しかし、 Kino などをインストールできないため、これをグラフ化することはできません
Smart Cell によるリモート接続
Livebook のホーム画面から右上の + New notebook をクリックし、新しいノートブックを開きます
セットアップセルに以下のコードを入力し、実行します
Mix.install([
{:kino, "~> 0.11"},
{:kino_vega_lite, "~> 0.1"}
])
リモート接続に必要なのは Kino だけです
KinoVegaLite は後でグラフ化するために追加しています
Smart Cell の Remote execution をクリックします
リモート実行用のフォームが表示されました
以下の内容を入力してください
-
NODE:
Phoenix 起動時に指定したノード名 +@<接続先のホスト名>
今回は接続先がローカルなので、ローカルマシンのホスト名を指定します
macOS の場合、scutil --get ComputerName
でローカルマシンのホスト名が取得できます -
COOKIE:
秘密情報なのでモーダルが開きます
Name に COOKIE 、 Value にPhoenix 起動時に指定したクッキーを入力します -
ASSIGN TO:
server_info
セルに以下のコードを入力します
PhoenixSampleWeb.Endpoint.server_info(:http) |> elem(1)
左上の Evaluate をクリックします
実行結果が表示されました
次のセルに以下のコードを入力し、実行します
server_info
実行結果
{{127, 0, 0, 1}, 4000}
ASSIGN TO に指定した変数に実行結果が格納されています
もう一つ Remote execution の Smart Cell を追加し、 ASSIGN TO を memory_usage
にして、今度は以下のコードを実行しましょう
Range.new(1, 10)
|> Enum.map(fn _ ->
Process.sleep(1000)
%{
datetime: Time.utc_now,
memory_usage: :erlang.memory(:total)
}
end)
実行結果
[
%{memory_usage: 62264192, datetime: ~T[00:40:06.003698]},
%{memory_usage: 62297544, datetime: ~T[00:40:07.013753]},
%{memory_usage: 62324520, datetime: ~T[00:40:08.014687]},
%{memory_usage: 62360928, datetime: ~T[00:40:09.016141]},
%{memory_usage: 62319392, datetime: ~T[00:40:10.016745]},
%{memory_usage: 62337720, datetime: ~T[00:40:11.017705]},
%{memory_usage: 62387992, datetime: ~T[00:40:12.018881]},
%{memory_usage: 62432032, datetime: ~T[00:40:13.019670]},
%{memory_usage: 62379944, datetime: ~T[00:40:14.020829]},
%{memory_usage: 62422032, datetime: ~T[00:40:15.021712]}
]
メモリ使用量の推移が取得できました
これをグラフ化しましょう
Chart の Smart Cell を追加します
以下のように指定し、 Evaluate をクリックします
- WIDTH: 700
- Chart: line
- x-axis の Type(歯車アインコンで表示): nominal
メモリ使用量がグラフ化できました
Remote execution の仕組み
先ほどの Smart Cell の右上鉛筆アイコンをクリックし、セルをコード化すると以下のようになります
node = :"phoenix_sample@oec-mac-book-1903"
Node.set_cookie(node, String.to_atom(System.fetch_env!("LB_COOKIE")))
memory_usage =
:erpc.call(node, fn ->
Range.new(1, 10)
|> Enum.map(fn _ ->
Process.sleep(1000)
%{datetime: Time.utc_now(), memory_usage: :erlang.memory(:total)}
end)
end)
Erlang の erpc モジュールによってリモート実行していることが分かります
まとめ
Attached node によるリモート接続では Kino などのモジュールを追加できないため、せっかくの Livebook の UI/UX を活かしきれませんでした
Remote execution の Smart Cell によって、リモート実行でも自由にモジュールを追加でき、高度な視覚化が実装できます