16
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ElixirAdvent Calendar 2022

Day 16

Elixir IExでphoenix_pubsubを使いメッセージの出版・購読を楽しむ

Last updated at Posted at 2022-12-08

Phoenixアプリでphoenix_pubsubを用いてメッセージを出版・購読するパターンがよく見られます。

実は、phoenix_pubsubPhoenixアプリ以外でも利用することができ、どんなElixirプロジェクトからでも同様のメッセージのやり取りをすることができます。

これからElixirを始める方にはこのサイトがおすすめです。

Elixirとコミュニティの雰囲気をゆるく味わいたい方は「先端ピアちゃん」さんの動画が超オススメです。

実験:一つのIEx上でphoenix_pubsub

対話ElixirシェルIExで試してみます。 ターミナルを開き、IExを起動します。

ターミナル
iex

phoenix_pubsubをインストールします。

IEx
iex> Mix.install([{:phoenix_pubsub, "~> 2.0"}])

Phoenix.PubSub.Supervisorを起動します。
通常はElixirプロジェクトのSupervisorの子プロセスとしてPhoenix.PubSub.Supervisorを起動することが多いと思いますが、ここでは手動で立ち上げます。

IEx
iex> Phoenix.PubSub.Supervisor.start_link(name: :my_pubsub)

余談ですがPhoenix.PubSub.SupervisorのソースコードはIEx.Helpers.open/1コマンドで開くことができます。

IEx
iex> open Phoenix.PubSub.Supervisor

話題を決めます。

IEx
iex> topic = "闘魂Elixir"

話題を購読します。

IEx
iex> Phoenix.PubSub.subscribe(:my_pubsub, topic)

話題に対してメッセージを出版します。

IEx
iex> Phoenix.PubSub.broadcast(:my_pubsub, topic, "元氣があればなんでもできる!")

郵便受けを確認します。

IEx
iex> flush
"元氣があればなんでもできる!"
:ok

ノードは任意の話題を購読するとその話題に対して出版されたメッセージを受け取ることができます。

:tada::tada::tada:

ただ自分で自分で出版したメッセージを自分で購読しても面白くないので、ノードを2つ(hogeノードとpiyoノード)立ち上げて同じことをやってみます。ノードは別々のPCでもOKです。

hogeノードがある話題を購読し、piyoノードが同じ話題に対してメッセージを出版したら、それがのhogeノード郵便受けに届くはずです。

実験:二つのノードでphoenix_pubsub 1

hogeノードを立ち上げます。

CMD
iex --sname hoge@localhost --cookie awesome_cookie

別のシェルでpiyoノードを立ち上げます。

CMD
iex --sname piyo@localhost --cookie awesome_cookie

両方のノードでphoenix_pubsubをインストールして(同じ名前の)Phoenix.PubSub.Supervisorを起動します。

hoge
iex(hoge@localhost)> Mix.install([{:phoenix_pubsub, "~> 2.0"}])

iex(hoge@localhost)> Phoenix.PubSub.Supervisor.start_link(name: :my_pubsub)
piyo
iex(piyo@localhost)> Mix.install([{:phoenix_pubsub, "~> 2.0"}])

iex(piyo@localhost)> Phoenix.PubSub.Supervisor.start_link(name: :my_pubsub)

hogeノードからpiyoノードに接続します。

hoge
iex(hoge@localhost)> Node.ping(:"piyo@localhost")
:pong

iex(hoge@localhost)> Node.list
[:piyo@localhost]

hogeノードで"闘魂Elixir"という話題を購読します。

hoge
iex(hoge@localhost)> Phoenix.PubSub.subscribe(:my_pubsub, "闘魂Elixir")
:ok

piyoノードで"闘魂Elixir"という話題に対してメッセージを出版します。

piyo
iex(piyo@localhost)> Phoenix.PubSub.broadcast(:my_pubsub, "闘魂Elixir", "元氣があればなんでもできる!")

hogeノードの郵便受けを確認。

hoge
iex(hoge@localhost)> flush
"元氣があればなんでもできる!"
:ok

piyoノードが出版したメッセージがhogeノードの郵便受けに届きました。

:tada::tada::tada:

出版-購読型モデルではノードからノードに直接メッセージを送るのではなく、ある話題に興味のある購読者が一斉にメッセージを受け取ることができます。

実験:二つのノードでphoenix_pubsub 2

同じことをもっと簡単にできればと思い、コードをパッケージ化しました。

hoge
iex

iex(hoge@localhost)> Mix.install([{:kantan_cluster, "~> 0.5.0"}])
iex(hoge@localhost)> KantanCluster.start_node(sname: :hoge, cookie: :awesome_cookie)
iex(hoge@localhost)> KantanCluster.subscribe("闘魂Elixir")
piyo
iex

iex(piyo@localhost) Mix.install([{:kantan_cluster, "~> 0.5.0"}])
iex(piyo@localhost) KantanCluster.start_node(sname: :piyo, cookie: :awesome_cookie)
iex(piyo@localhost) KantanCluster.broadcast("闘魂Elixir", "元氣があればなんでもできる!")
hoge
iex(hoge@localhost)> flush
"元氣があればなんでもできる!"
:ok

簡単に出版-購読型モデルを楽しめました!

:tada::tada::tada:

:erpc.call/4で遠隔手続き呼出し

それに対して、直接特定のノードにメッセージを送りたいときは:erpc.call/4を用いた遠隔手続き呼出しが便利そうです。

phoenix_pubsubErlangpgモジュールを使って実装されているようです。詳しいことは知りません。

ご参考までに

16
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?