OTP:サーバ メモ

November 02, 2021

『プログラミングElixir』(第1版)の「第16章 OTP:サーバ」を読んだメモを記していく。

GenServerコールバック

GenServerには6つのコールバックがある。
use Genserverを使うことによって、ユーザーは実装する必要のあるコーバルックだけ実装すれば良い。

init(start_arguments)

新しいサーバ開始時にGenServerから呼ばれる。
サーバ開始に成功すれば{:ok, state}を返し、開始できないなら{:stop, reason}を返す。
タイムアウトの指定も可能。

handle_call(request, from, state)

クライアントがGenServer.call(pid, request)を使った時に呼ばれる。
requestパラメータは、リクエストの種類をアトムで渡す(:next_number, :set_numberなど)
fromパラメータは、クライアントのPIDとユニークタグを含むタプル。
stateパラメータは、サーバの状態を持つ。

成功時には{:reply, result, new_state}を返す。
実装されていないrequest種類が呼ばれると:bad_callエラーを返す。

handle_cast(request, state)

GenServer.cast(pid, request)を使ったときに呼ばれる。
レスポンスが必要ない処理を実装する際に用いる。
成功時は{:noreply, new_state}{:stop, reason, new_state}を返す。

handle_info(info, state)

timeoutメッセージ、リンクしたプロセスからの終了メッセージ、sendを用いてPIDへ送られたメッセージなど、callやcastリクエスト以外でやってくるメッセージを処理する。

terminate(reason, state)

サーバが終了しようとするときに呼ばれる。 サーバに監視をつけてしまえば、これについて考える必要はない(要調査)

code_change(from_version, state, extra)

OTPが、走っているサーバを古いバージョンから新しいバージョンへ(無停止で)置き換える際に呼ばれる。
古い状態のフォーマットを新しいフォーマットへ変換するなどの処理を行う

format_status(reason, [pdict, state])

:sys.get_status pidなどサーバの状態の表示する際に表示方法をカスタマイズするために使う。

callとcastのレスポンス

callとcastのレスポンスには、いくつかのオプションを返すことができる

  • :hibernate

:hibernateをレスポンスに含めた場合、次のリクエストまでメモリ上からサーバの状態を取り除き、次のリクエストがあれば状態を読み込んで復活する。
メモリを節約できるがCPUを余分に使う。

  • タイムアウトオプション

:infiniteかミリ秒を渡してタイムアウト時間を指定できる。
ミリ秒が渡された場合は、その時間までにサーバが何もしない(次のリクエストを送らない?)ならタイムアウトメッセージが送られる。

レスポンスのパターン

下記二つはcall, cast共通

{:noreply, new_state [, :hibernate | timeout]}

{:stop, reason, new_state} // サーバに停止の合図をする

下記二つはhandle_callだけがレスポンスできる。

{:reply, response, new_state [ , :hibernate | timeout]} // クライアントにresponseを送る

{:stop, reason, reply, new_state} // レスポンスを送り、サーバに停止の合図をする。

プロセスの名前を付ける