Slide 1

Slide 1 text

Elixir の GenServer で アクタープログラミングしてみよう 〜Pub/Sub使って広域分散環境でマイグレーションも出来るよ〜 ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12

Slide 2

Slide 2 text

今日のお題 ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 ● Elixir はどこがなにが嬉しいのか ● 並行プログラミングのしあわせ ● ライブプロセスマイグレーション 2

Slide 3

Slide 3 text

Acknowledgement ● NICT ○ ● Government of Kochi Prefecture, Japan ○ ● Budget: The commissioned research (No.04001) by the National Institute of Information and Communications Technology, Japan. Budget: Research promotion projects for industry creation through industry-academia-government collaboration (2020) Softbank ○ 広域分散実行基盤の実現に寄与する通信技術に関する共同研究 ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 3

Slide 4

Slide 4 text

きくゆた… について @kikuyuta ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 4

Slide 5

Slide 5 text

Elixir はこんな風 defmodule Fib do def onacci(0), do: 0 def onacci(1), do: 1 def onacci(n) do onacci(n-2)+onacci(n-1) end end ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 iex(1)> Fib.onacci(0) 0 iex(2)> Fib.onacci(1) 1 iex(3)> Fib.onacci(6) 8 5

Slide 6

Slide 6 text

パイプ使った例 defmodule Fib do def onacci(0), do: 0 def onacci(1), do: 1 def onacci(n) do onacci(n-2)+onacci(n-1) end def seq(n) do 0..n |> Enum.map(&onacci/1) |> Enum.each(&IO.puts/1) end end ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 iex(1)> Fib.seq(5) 0 1 1 2 3 5 :ok 6

Slide 7

Slide 7 text

パイプでこんな風にも書ける defmodule Fib do def onacci(0), do: 0 def onacci(1), do: 1 def onacci(n) do onacci(n-2) |> Kernel.+(onacci(n-1)) end end ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 h(g(f(x))) を x |> f |> g |> h と書ける 7

Slide 8

Slide 8 text

関数型言語でモノを制御したくなる ● Elixir なら関数型由来の嬉しさに加えて… I/O抽象化との親和性 ○ Bit列パターンマッチ ○ 並行プログラミング ○ Let it Crash! 思想 ○ ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 8

Slide 9

Slide 9 text

関数型言語を産業で使おう ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 9

Slide 10

Slide 10 text

I/O 抽象化との親和性 ● 全部 API プロセスでくるむ P1 アプリケーション ソフトウェア P2 でも関数型で状態をどうあつかうの? ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 P3 10

Slide 11

Slide 11 text

Erlang/OTP (1986〜, 1998〜) Ericsson のATM交換機に採用された (Wikipedia:en) ● イミュータブルな変数 ● パターンマッチ ● アクターモデル ● ○ ○ 軽量プロセスとメッセージパッシング スーパバイザ、プロセスツリー、Let it Crash Prolog ライクな文法 ● BEAM VM ⇒ Elixir, Gleam ● ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 11

Slide 12

Slide 12 text

Elixir (2012〜) José Valim ● Erlang ベースでもっとプログラミングを楽しく… ● ○ 文法:Prolog 風 → Ruby 風 新機能:パイプ演算子、マクロ、Protocol、mix、hex… ● プラットフォーム ● ○ ○ ○ Web開発用:Phoenix, Liveview IoT・組込み用:Nerves AI用:Nx, Axon, Bumblebee ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 12

Slide 13

Slide 13 text

Elixir ならではなのは何? ● たいがいの機能は他の言語でも実現できそう ○ ● 実際に実装するかどうかは別として… では Elixir がぶっ飛んでるのは… ○ ○ ○ 並行プログラミング(これ自体は Erlang/OTP 由来) 特に GenServer によるプロセスプログラミング ■ Erlang にもあるけど、Elixir のほうがいろいろと簡単 スーパバイザツリーと Let it Crash ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 13

Slide 14

Slide 14 text

GenServer とは ● Elixir/Erlang でプロセスを使うための標準ラ イブラリ (behaviour) ● サーバ・クライアント型サービスを作成 ● スーパバイザツリーによる監視・再起動 ● 状態変数あり ● ● ● ● ● 初期化・動作開始 クライアントとの同期通信動作 クライアントとの非同期通信動作 プロセスからのメッセージ 終了 start or start_link stop handle_call GenServer handle_cast terminate Process state handle_info message other (or self) process ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 init call cast

Slide 15

Slide 15 text

GenServer で Stack を作る defmodule Stack do use GenServer def start_link(pname) do GenServer.start_link(__MODULE__, nil, name: pname) end def init(_arg) do {:ok, []} end def push(pname, ele) do GenServer.cast(pname, {:push, ele}) end def handle_cast({:push, ele}, state) do {:noreply, [ele, state]} end def pop(pname) do GenServer.call(pname, :pop) end def handle_call(:pop, _from, [ele|rest]) do {:reply, {:ok, ele}, rest} end end ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12

Slide 16

Slide 16 text

Stack プロセスの動作 iex(1)> Stack.start_link(:afo) {:ok, #PID<0.147.0>} iex(2)> Stack.push(:afo, 0) :ok iex(3)> Stack.push(:afo, 1) :ok iex(4)> Stack.pop(:afo) {:ok, 1} iex(5)> Stack.start_link(:bar) {:ok, #PID<0.148.0>} iex(6)> Stack.push(:bar, "hello") :ok iex(7)> Stack.pop(:bar) {:ok, "hello"} iex(8)> Stack.pop(:afo) {:ok, [0, []]} ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 push pop #PID<0.147.0> [1, 0] Iex (REPL) :afo #PID<0.148.0> pop push [“hello”] :bar

Slide 17

Slide 17 text

異なる BEAM VM のプロセスでもお話できる #PID<0.1.0> ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 #PID<0.2.0>

Slide 18

Slide 18 text

どっかの BEAM VM に飛ばせる Store MEC ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 18

Slide 19

Slide 19 text

プロセスをマイグレーションする ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12

Slide 20

Slide 20 text

状況が静的に落ち着いているなら良いのだが… Store MEC ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 MEC MEC 20

Slide 21

Slide 21 text

クライアントはどっかに行っちゃうかも… MEC ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 MEC 21

Slide 22

Slide 22 text

そして昨今は人工衛星にサーバが乗るとも聞くし… ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 22

Slide 23

Slide 23 text

サーバもどっかに行っちゃうかも… ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 23

Slide 24

Slide 24 text

ならば動いてるプロセスもどっかに行かせたい … MEC ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 MEC 24

Slide 25

Slide 25 text

プロセスマイグレーションへの動機 クライアント・サーバ間で最適なRTTを維持したい ● 長時間いごくないしは永続的に動くプロセスを中断した くない ● 設備のメンテナンスの影響を受けたくない ● より強力なサーバに移動して実行したい ● 電力供給状況の良いサーバに逃がしたい ● ○ 再生可能エネルギーでデータセンターの電源を賄ってる場合など ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 25

Slide 26

Slide 26 text

マイグレーションの考え方 計算エンティティA なるべく環境によらず通信可能に なにか事前準備をしておく なにか事前準備をしておく なにか計算する動作が始まる なるべく面倒くさくなく なるべく簡単に、速く、少なく … お仕事を続ける … 計算動作を止める 必要な情報を送り出す 渡せるものを多く 渡せないものを少なく ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 計算エンティティB 必要な情報を受け取る それに従って計算する動作を始める … お仕事を続ける … 26

Slide 27

Slide 27 text

何をマイグレートするか GenServer! ● 物理サーバそのもの ○ ● 仮想マシン/仮想OS ○ ● サーバ本体やホストOSは動かさない ERTS (Erlang Run Time System) ○ ● どうしてもやるとおっしゃるなら止めませんが… 仮想マシンやゲストOSは動かさない Elixir/Erlang プロセス(アクター) ○ ERTS は動かさない ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 27

Slide 28

Slide 28 text

広域ネットワークを使う上での問題 ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 28

Slide 29

Slide 29 text

Erlang Cluster の制約 Node ● Node.connect で簡単にクラスタリ ングできるのではあるものの… ● 完全グラフを作るのでスケールす るか疑わしい ● TCP/UDP/IP 通信が透過的でないと ならない Node Node Node Node Node ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 Node Node 29

Slide 30

Slide 30 text

TCP/UDP/IP通信の透過性 ● 典型的には NAPT がある ○ ○ IPv4アドレスの消費を押さえる グローバル側からの侵入を止める ● CGN なんてのも導入されてる ● 携帯網内がグローバル環境でない ● TCP/UDP セッションをローカル からグローバル方向にしか張れな い ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 Router Router NAPT Node Node Node Node.connect() Node.connect() true false 30

Slide 31

Slide 31 text

IP通信の透過性を実現する手法 常に使えるとは限らない ● 状況を維持し続けるのが大変 ● Router Router Router NAPT Node NAPT Node VPN Tunneling ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 Router Node Node NAPT hole punching 31

Slide 32

Slide 32 text

そうだ Zenoh にしよう ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 32

Slide 33

Slide 33 text

Zenoh とは ● Pub/Sub モデル ○ ○ ○ ● ● Pub が発信したメッセージを Sub が受信 事前に共通の key (topic) を決めておく Zenoh: Pub/Sub、Queryable、Storage 非中央集権型 ○ ○ ● https://zenoh.io/ 完全な分散型 MQTTのようなブローカが不要 key に構造を持たせられる ○ UNIX ディレクトリ風 Open Source (Linux Foundation) ○ https://github.com/eclipse-zenoh ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 33

Slide 34

Slide 34 text

Zenohex: Elixir 用の API ライブラリ https://hex.pm/packages/zenohex ● https://github.com/biyooon-ex/zenohex ● Elixir App Zenohex Rustler Zenoh TCP/UDP IP ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 Go App Rust App Python App C App C++ App Zenoh TCP/UDP IP Zenoh TCP/UDP IP Zenoh TCP/UDP IP Zenoh TCP/UDP IP Zenoh TCP/UDP IP 34

Slide 35

Slide 35 text

Zenoh で複雑さの軽減 Node Node Node Node Node Node Node Node Node Node Node Node Node ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 Node Node Node 35

Slide 36

Slide 36 text

Zenoh を用いたGenServerプロセスのマイグレーション Zenoh での通信手段を持っている use GenServer use GenServer GenServer でプロセスを起動 … プロセスがお仕事を続ける … プロセスを止める モジュールと状態を送り出す ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 モジュールと状態を受け取る モジュールをロードする GenServer でもらった状態でプロセス起動 … プロセスがお仕事を続ける … 36

Slide 37

Slide 37 text

GenServer プロセスのマイグレーション (その1) Zenoh で通信できるものと仮定 use GenServer use GenServer start/3 で GenServer 起動 :code.get_object_code/1 で module ゲット stop/3 で停止 terminate/3 の返り値 (reason, state) ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 :code.load_binary/3 で module をロード start/3 で state を初期値として起動 37

Slide 38

Slide 38 text

GenServer プロセスのマイグレーション (その2) Zenoh で通信できることを仮定 use GenServer use GenServer :code.get_object_code/1 to get module :code.load_binary/3 to load the module start/3 で GenServer プロセスを起動 start/3 で GenServer プロセスを起動 :sys.suspend/1 で直ちに停止しておく :sys.suspend/1 でサスペンドする :sys.get_state/2 で状態をゲット :sys.replace_state/2 で状態注入 :sys.resume/1 でプロセス再開 ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 38

Slide 39

Slide 39 text

GenServer マイグレーションのデモ Subscriber Elixir ubuntu ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 Elixir Apps Publisher Elixir MacOS 39

Slide 40

Slide 40 text

左側 石狩 右側 バンクーバー ⾼知⼯科⼤学 菊池豊 IPSJ PRO 2026-06-05 42

Slide 41

Slide 41 text

Subscribing the same key Subscriber Elixir ubuntu Subscriber Elixir ubuntu ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 Subscriber Elixir ubuntu Elixir Apps Publisher Elixir MacOS 43

Slide 42

Slide 42 text

左側 石狩 中央 石狩 右 バンクーバー ⾼知⼯科⼤学 菊池豊 IPSJ PRO 2026-06-05 44

Slide 43

Slide 43 text

⾼知⼯科⼤学 菊池豊 IPSJ PRO 2026-06-05 45

Slide 44

Slide 44 text

ご清聴 ありがとうございました ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 46

Slide 45

Slide 45 text

参考文献・コード ● Giocci についてより詳しくは… ○ ● ElixirConf Goatmire 2025 in Varberg, Sweden 小水力発電システムへの応用については… ○ ○ NervesConf EU 2025 in Varberg, Sweden CodeBeam America 2022 in Mountain View, US Giocci: https://github.com/biyooon-ex/giocci_platform ● Zenohex: https://github.com/biyooon-ex/zenohex ● ModBuzz: https://github.com/tombo-works/modbuzz ● ○ Yet another sophisticated MODBUS library on both TCP and RTU (RS485) ⾼知⼯科⼤学 菊池豊 関数型まつり 2026-07-12 47