[Elixir]handle_infoとreply

GenServerなんかにある handle_info/2 の使い方をど忘れしてしまったので、メモ。

自身のブログを検索すると、 [Elixir in Action]OTP/GenServerを学んで非同期/並行処理を学ぶ にすでにメモってたのですが。

以下のような簡単なコールバックを実装し、スクリプトを実行してみます。

まずはGrnServerを持つプロセスを生成します。そのあと、 callcast で定義されていないメッセージを send してあげると、ここでは handle_info/2 に拾われて処理を行います。

defmodule MyInfo do
  use GenServer

  # Callbacks

  def handle_info({:reply, msg}, state) do
    IO.inspect msg
    IO.inspect state
    {:noreply, state}
  end
  def handle_info(_msg, state) do
    {:noreply, state}
  end
end
# Start the server
{:ok, pid} = GenServer.start_link(MyInfo, ["hello"])

# send message to the process
Process.send_after pid, {:reply, "message"}, 1_000

# "message"
# ["hello"]

少し話がそれて、非同期通信の時に何らかの処理を終えた時に通知を受け取りたい場合、そういえば以下のように reply/2 を使って処理を非同期にプロセスに投げることできるのでしたね。上に貼ったリンク先を読み直してて思い出した…

def hanldle_call(....) do
  spawn(fn ->
    data = # 処理
    GenServer.reply(caller, data) # 処理が終われば、GenServerの機構でメッセージを送る
  end)

  {:noreply, do_folder} # まずは非同期的に応答する
end

handle_infoも使うと、以下の通りにも書くことができる、と。
ここの、GenServerのドキュメントにも載っているやり方です。

def handle_cast(:reply_in_one_second, from, state) do
  Process.send_after(self(), {:reply, from}, 1_000)
  {:noreply, state}
end

def handle_info({:reply, from}, state) do
  GenServer.reply(from, :one_second_has_passed)
end

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中