Mnesia で永続化したテーブルに関数を入れ、全ノード停止後に再起動し、別ノードで実行したら動いた(まー、動いて当たり前ですけど)

id:cooldaemon:20071011:1192094209 で Mnesia 上のテーブルをディスクに保存しましたが、そのテーブルに関数を入れて遊んでみました。

前回作ったノード a を再起動し、io:fwrite/2 を保存する。

% erlang -sname a
(a@imac)1> mnesia_test:restart().
ok
(a@imac)2> mnesia_test:set(func1, fun io:fwrite/2).
{atomic,ok}

前回作ったノード b を再起動し、io:fwrite/2 を取得して実行する。
その後、ノード b を停止する。

% erlang -sname b
(b@imac)1> mnesia_test:restart().
ok
(b@imac)2> [Func1] = mnesia_test:get(func1).
[#Fun<io.fwrite.2>]
(b@imac)3> Func1("test~n", []).
test
ok
(b@imac)4> halt().

ノード a を停止後、すぐに再起動し、io:fwrite/2 を取り出して実行する。

(a@imac)3> halt().
% erlang -sname a
(a@imac)1> mnesia_test:restart().
ok
(a@imac)2> [Func1] = mnesia_test:get(func1).
[#Fun<io.fwrite.2>]
(a@imac)3> Func1("test~n", []).
test
ok

一度全てのノードを停止したにも関わらず、関数は実行できる。

続けて、ノード b を再起動し、こちらでも io:fwrite/2 が実行できる事を確認する。
更に、無名関数を保存し、ノード b を停止する。

% erlang -sname b
(b@imac)1> mnesia_test:restart().
ok
(b@imac)2> [Func1] = mnesia_test:get(func1).
[#Fun<io.fwrite.2>]
(b@imac)3> Func1("test~n", []).
test
ok
(b@imac)4> Func2 = fun () -> io:fwrite("test2~n", []), ok end.
#Fun<erl_eval.20.112921583>
(b@imac)5> Func2().
test2
ok
(b@imac)6> mnesia_test:set(func2, Func2).
{atomic,ok} 
(b@imac)7> Func3 = mnesia_test:get(func2).
[#Fun<erl_eval.20.112921583>]
(b@imac)8> Func3().
test2
ok
(b@imac)9> halt().

ノード a で、ノード b で作った無名関数を取得し、実行できる事を確認する。
その後、ノード a を再起動しても実行できる事を確認する。

(a@imac)4> [Func3] = mnesia_test:get(func2).
[#Fun<erl_eval.20.112921583>]
(a@imac)5> Func3().
test2
ok
(a@imac)6> halt().
% erl -sname a
(a@imac)1> mnesia_test:restart().
ok
(a@imac)2> [Func3] = mnesia_test:get(func2).
[#Fun<erl_eval.20.112921583>]
(a@imac)3> Func3().
test2
ok

無名関数の中に、ノード b でしか実行できない関数を実行するコードを入れると、当然、ノード a で実行した際にエラーとなる。

ジョブを登録して実行とかに使えそう。