LoginSignup
8
4

More than 1 year has passed since last update.

Elixirの分散型DB MnesiaをGenServerでイベントドリブン

Last updated at Posted at 2021-07-01

はじめに

データーベースでイベントドリブンしたい。

この記事は
物の状態をイベントドリブンで取得するために、DBへの他ノードからの書き込みや削除のイベントをGenServerで取得します。

qiita用スライド #大崎.png

分散型DB(Mnesia)を複数のマシンで実行した記事はこちら
Nerves+Phoenix 003 エムネチカ:分散型DB Mnesiaを使ってオリジナルCapeのLEDをエムネチカ

参考

環境

  • macOS
  • elixir 1.10.3-otp-23
  • erlang 23.0.2

目次

  • GenServer
  • Mnesiaの開始
  • GenServerの開始
  • 実行
  • 次回は

GenServer

GenServerを作成:initでsubscribe開始、handle_infoで受信

mnesiatrigger.exs
defmodule Mnesiatrigger do
  use GenServer
  require Logger

  def start_link(pname, table_name, ppid \\ []) do
    GenServer.start_link(__MODULE__, {table_name , ppid},name: pname)
  end

  def init({table_name, ppid}) do
    # テーブルに関するイベントをsubscribeの対象とする。
    {:ok,mnesiaref} = :mnesia.subscribe({:table, table_name, :simple})
    {:ok,mnesiaref}
  end

  # テーブルへのイベントが発生した場合にメッセージを受信
  def handle_info({:mnesia_table_event,
      {write, {tbl, key, val}, from} = msg},state) do
      IO.inspect("書き込み: table: #{tbl}, key: #{key}, value: #{val}, from: #{inspect(from)}")
    {:noreply, state}
  end

  def handle_info({:mnesia_table_event,
      {delete, {tbl, key}, from} = msg},state) do
      IO.inspect("削除: table: #{tbl}, key: #{key}, from: #{inspect(from)}")
    {:noreply, state}
  end

  # デバッグ用
  # def handle_info({:mnesia_table_event, value = msg},state) do
  #   IO.inspect("#{inspect(value)}")
  #   {:noreply, state}
  # end
end

Mnesiaの開始

まずNode:aでSchema、Tableの作成まで実行

Node->a
iex --name a@192.168.1.61 --cookie comecomeeverybody ./mnesiatrigger.ex
# 停止
iex> :mnesia.stop()
:stopped

# スキーマ削除
iex> :mnesia.delete_schema([node()])
:ok

# スキーマ作成
iex> :mnesia.create_schema([node()])
:ok

# 開始
iex> :mnesia.start()
:ok

# テーブル作成
iex> :mnesia.create_table(Exi, [attributes: [:key, :value]])
{:atomic, :ok}

次にNode:bでMnesiaを開始

 Node->b
iex --name b@192.168.1.61 --cookie comecomeeverybody
# 停止
iex> :mnesia.stop()
:stopped

# 開始
iex> :mnesia.start()
:ok

次にNode:aでNode:bをNodeに追加

 Node->a
# ノードの追加
iex> :mnesia.change_config(:extra_db_nodes, [:"b@192.168.1.61"])
{:ok, [:"b@192.168.1.61"]}

GenServerの開始

Node:aでGenServerを起動

Node->a
iex> Mnesiatrigger.start_link(:mnetest, Exi, self())
{:ok, #PID<0.206.0>}

実行

  • 実行順
    • Node:bでdirty_write
    • Node:bでdirty_delete
    • Node:bでtransaction、write

実行結果

次回は

kochi.exからは
@nishiuchikazuma さんがMnesiaのrapper「Memento」をご紹介。

8
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4