たまたまあるソースコードを読んでいたらpersistent_termという面白そうなErlangモジュールに出くわしました。
persistent_termとは
- OTP 21.2から導入された
- Erlang Term Storage (ETS)と同様に高速で値を取得できるインメモリKey-Valueストレージ
- ETSと異なり読み込みに特化して最適化されており、その代償として書き込みは遅い
- BEAMバーチャルマシンに対して1インスタンス存在し、どのモジュールからもアクセスできる
- 衝突を防ぐため、モジュール名もしくはモジュール名と何か他のErlang Termと組み合わせたタプルをキーをすることが推奨されている
- 例、
MyModule
- 例、
{MyModule, :secret_code}
- 例、
詳しくはErlangの公式ドキュメントをご覧ください。
ETSについては以前軽くまとめたものがあるので参考になれば幸いです。
論よりRUN
IExシェルを起動
iex
persistent_term
の中身を見てみる
iex> :persistent_term.get()
...long list...
iex> :persistent_term.get() |> length()
22
なんと、まだ何もしていないのにネットワーク関係やロガー関係の設定が保存されているようです。
ですので、それらの値を誤って消さないように、やっぱりキーの名前空間に注意が必要ですね。
適当なキーでアクセスしてみる
iex> :persistent_term.get(:foo)
** (ArgumentError) errors were found at the given arguments:
* 1st argument: no persistent term stored with this key
:persistent_term.get(:foo)
iex:3: (file)
キーが存在しない場合はエラーになるようです。
値を挿入してみる
iex> :persistent_term.put({MyApp, "feeling"}, "good")
:ok
iex> :persistent_term.put({MyApp, "language"}, "Japanese")
:ok
簡単ですね。
値を取得してみる
iex> :persistent_term.get({MyApp, "feeling"})
"good"
iex> :persistent_term.get({MyApp, "language"})
"Japanese"
これも楽勝。
何に使えるのか
- 一度書き込まれたら読み込みしかされない設定関係に使えそう
事例研究: elixir-toniq/mentat
キャッシュに使えるElixirパッケージは複数存在していますが、その一つであるelixir-toniq/mentatにpersistent_termが利用されていました。
やはりSupervisorのinitコールバックで一度だけ書き込みをしてあとは読み込むだけという使い方をしています。
じゃ、また。
ご参考までに