LoginSignup
4
0

More than 3 years have passed since last update.

Elixirのノード、プロセス間通信

Posted at

はじめに

プログラミングElixirの「15.2 プロセスの名前付け」を理解するための備忘録です。
概要:とあるコールバックプロセスのPIDを登録し、そのPIDに対して2秒間隔でメッセージを送信するプログラム
異なるノードからコールバックプロセスを登録できるようにする。

参考

プログラミングElixir「15.2 プロセスの名前付け」

環境

  • IEx 1.9.1 (compiled with Erlang/OTP 22)

目次

  • ソース
  • ノード1で実行
  • ノード2で実行
  • まとめ

ソース

ticker.ex
defmodule Ticker do
  @interval 2000 # 2 seconds
  @name :ticker
  def start do
    # 関数generatorのプロセスを開始
    pid = spawn(__MODULE__, :generator,[[]])
    # 開始した関数generatorを名前「ticker」として登録
    :global.register_name(@name, pid)
  end

  def register(client_pid) do
    # ticker(関数generator)に{ :register, client_pid }を送信
    send :global.whereis_name(@name), { :register, client_pid }
  end

  def generator(clients) do
    receive do
      # 関数registerから呼ばれた場合に実行
      {:register, pid} ->
        # code
        IO.puts "registering #{inspect pid}"
        generator([pid|clients])
      after
        # 2秒間隔で実行
        @interval ->
          IO.puts "tick"
          Enum.each clients, fn client ->
            # モジュールClientの関数receiverへメッセージ「:tick」を送信
            send client, { :tick }
          end
          # 再帰
          generator(clients)
    end
  end
end

defmodule Client do
  def start do
    # 関数receiverのプロセスを開始
    pid = spawn(__MODULE__, :receiver,[])
    # 関数registerを実行(pid=receiver)
    Ticker.register(pid)
  end
  def receiver do
    receive do
      # 関数generatorからのメッセージ受信
      {:tick} ->
        # code
        IO.puts "tock in client"
        # 再帰
        receiver
    end
  end
end

ノード1で実行

% iex --sname one
iex(one@kochiex)1> c("ticker.ex")
[Client, Ticker]
iex(one@kochiex)2> Node.connect :"two@kochiex"
true         
iex(one@kochiex)3> Node.list
[:"two@kochiex"]
iex(one@kochiex)4> Ticker.start
:yes
tick
tick
tick
iex(one@kochiex)5> Client.start
registering #PID<0.128.0>
{:register, #PID<0.128.0>}
tick
tock in client
tick
tock in client
tick
tock in client
tick
tock in client
# Node twoでClient.startを実行
registering #PID<15299.123.0> 
tick
tock in client
tick
tock in client

ノード2で実行

%  iex --sname two
iex(two@kochiex)1> c("ticker.ex")
[Client, Ticker]
iex(two@kochiex)2> Node.list
[:"one@kochiex"]
iex(two@kochiex)3> Client.start    
{:register, #PID<0.123.0>}
tock in client
tock in client

まとめ

次回はGenServer の つもり。

4
0
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
4
0