Erlang Supervisor 的 error:{badmatch,{error,{{start_spec,{invalid_modules, ??? }} 错误解决

新人,刚开始学习 erlang ,使用 rebar 生成了一个标准的 otp 应用程序,往 Supervisor 加了一个 gen_server ,却通不过默认单元测试了。提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
gamexg@vps1:~/erl/cw$ rebar compile eunit
==> cw (compile)
Compiled src/cw_dnode.erl
Compiled src/cw_sup.erl
Compiled src/cw_app.erl
==> cw (eunit)
 
=INFO REPORT==== 18-Apr-2011::14:53:47 ===
    application: cw
    exited: {{start_spec,{invalid_modules,cw_dnode}},
             {cw_app,start,[normal,[]]}}
    type: temporary
cw_app: simple_test (module 'cw_app')...*failed*
::error:{badmatch,{error,{{start_spec,{invalid_modules,cw_dnode}},
                        {cw_app,start,[normal,[]]}}}}
  in function cw_app:simple_test/0
 
 
=======================================================
  Failed: 1.  Skipped: 0.  Passed: 0.
Cover analysis: /home/gamexg/erl/cw/.eunit/index.html
ERROR: One or more eunit tests failed.

最后发现原因是回调模块应该是列表,我却直接把模块名填上了….

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-module(cw_sup).
 
-behaviour(supervisor).
 
%% API
-export([start_link/0]).
 
%% Supervisor callbacks
-export([init/1]).
 
%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).
 
%% ===================================================================
%% API functions
%% ===================================================================
 
start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).
 
%% ===================================================================
%% Supervisor callbacks
%% ===================================================================
 
init([]) ->
    {ok, { {one_for_one, 5, 100}, 
        [
            {dnode,
                {cw_dnode,start_link,[]},
                permanent,
                10000,
                worker,
                cw_dnode                                 % 这里错了,应该是 [cw_dnode] ,是列表。
            }
        ]
       } }.

No comment »

导入测试数据到 Mnesia 数据库

假如我们开始玩一个关于健康食品的小型数据库,可输入下列数据到文件data.txt:

1
2
3
4
5
6
7
8
9
{tables,[
    {fruit, [{attributes, [name, color, taste]}]},
    {vegetable, [{attributes, [name, color, taste, price]}]}
]}.
 
{fruit, orange, orange, sweet}.
{fruit, apple, green, sweet}.
{vegetable, carrot, orange, carrotish, 2.55}.
{vegetable, potato, yellow, none, 0.45}.

下列Erlang shell会话显示如何加载fruits数据库:

 $ erl
Erlang (BEAM) emulator version 5.6.3 [source] [smp:2] [async-threads:0] [kernel-poll:false]

Eshell V5.6.3 (abort with ^G)
1> mnesia:start(). % 虽然 mnesia:load_textfile 也会启动数据库,但是在处理上次遗留的内存数据库上有问题,
会保留上次非正常退出时的内存表的结构,造成本次 mnesia:load_textfile 操作失败。出现注1的错误,造成无法导入本
次的数据。
ok
2> mnesia:load_textfile("data.txt").
New table fruit
New table vegetable
{atomic,ok}
3> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
vegetable : with 2 records occupying 320 words of mem
fruit : with 2 records occupying 312 words of mem
schema : with 3 records occupying 622 words of mem
===> System info in version "4.4.3", debug level = none <===
opt_disc. Directory "/home/gamexg/erl/mnesia/Mnesia.nonode@nohost" is NOT used.
use fallback at restart = false
running db nodes = [nonode@nohost]
stopped db nodes = []
master node tables = []
remote = []
ram_copies = [fruit,schema,vegetable]
disc_copies = []
disc_only_copies = []
[{nonode@nohost,ram_copies}] = [schema,fruit,vegetable]
5 transactions committed, 0 aborted, 0 restarted, 0 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok
4>

这里我们能够看到怎样从一个规范的文本文件来初始化数据库管理系统。

注1:不使用mnesia:start 启动数据库直接载入数据会使上次运行的内存表未被清除,而和本次导入的表冲突,导入失败。

$ erl
Erlang (BEAM) emulator version 5.6.3 [source] [smp:2] [async-threads:0] [kernel-poll:false]

Eshell V5.6.3 (abort with ^G)
1> mnesia:load_textfile("data.txt").
** Table fruit already exists on nowhere, just entering data
** Table vegetable already exists on nowhere, just entering data
{aborted,{no_exists,fruit}}
2>

No comment »