GenServerなんかにある handle_info/2 の使い方をど忘れしてしまったので、メモ。
自身のブログを検索すると、 [Elixir in Action]OTP/GenServerを学んで非同期/並行処理を学ぶ にすでにメモってたのですが。
以下のような簡単なコールバックを実装し、スクリプトを実行してみます。
まずはGrnServerを持つプロセスを生成します。そのあと、 call や cast で定義されていないメッセージを 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