ある程度複雑なNervesファームウエアを作ると何らかのデータを保存したくなることがあると思います。
Nervesはファームウエアは意図しないデータの破壊を防ぐために基本的には読み取り専用になっているのですが、一箇所だけ書き込める場所があります。/data
ディレクトリーです。
iex> ls "/data"
.cache .erlang.cookie last_shutdown.txt lost+found vintage_net
iex> File.write!("/data/hello.txt", "こんにちは!\n")
:ok
iex> ls "/data/hello.txt"
/data/hello.txt
iex> cat "/data/hello.txt"
こんにちは!
iex> File.rm("/data/hello.txt")
:ok
/data
ディレクトリーには自由にファイルを作って保存ができるのですが、頻繁にデータ保存をしたい場合にはデータベースが欲しくなります。
Nervesで使えるファイルベースのデータベースはいくつか挙げられます。
個人的に特に気に入っているのがcubdbです。
cubdbの特徴
- 100%Elixirで書かれている。
- 活発にメンテナンスされている。(2021年現在)
- Nervesコアチームも使っているらしい。(特にJon Jonさん)
- 関数がシンプルでわかりやすい。
- データ汚染を防ぐ仕組みも実装されている。
IExで試運転
-
data_dir
に対して複数のプロセスを立ち上げるとプログラムがクラッシュするので、それを未然に防ぐためにプロセスに名前をつけておくのがコツです。
# IExを起動
iex
# cubdbをインストール
Mix.install([:cubdb])
# データの保存先とプロセス名を指定してcubdbサーバーを起動
data_dir = Path.join(System.tmp_dir!(), "database")
{:ok, _db} = CubDB.start_link(data_dir: data_dir, name: :my_database)
CubDB.put(:my_database, :feeling, "awesome")
#=> :ok
CubDB.get(:my_database, :feeling)
#=> "awesome"
CubDB.delete(:my_database, :feeling)
#=> :ok
CubDB.get(:my_database, :feeling)
#=> nil
Nervesファームウエアに搭載
cubdbを依存関係リストに追加して、mix deps.get
コマンドでインストール。
mix.exs
defp deps do
[
{:cubdb, "~> 1.1"},
]
アプリ起動時にcubdbサーバーを起動する。
lib/hello_nerves/application.ex
defmodule HelloNerves.Application do
@moduledoc false
use Application
def start(_type, _args) do
opts = [strategy: :one_for_one, name: HelloNerves.Supervisor]
children = [
{CubDB, [
# Nervesで書き込める場所`/data`配下の任意のディレクトリーを指定
data_dir: "/data/database",
# CubDBプロセスに名前をつける
name: HelloNerves.Database]}
]
Supervisor.start_link(children, opts)
end
後はIExでの試運転同様にNervesファームウエアで自由に読み書きできます。
Elixirコミュニティに初めて接する方は下記がオススメです
Elixirコミュニティ の歩き方 -国内オンライン編-
https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian