【问题标题】:Mnesia can't create tables when ran by Yaws, but can when ran from the Erlang shell当 Yaws 运行时,Mnesia 不能创建表,但从 Erlang shell 运行时可以
【发布时间】:2017-03-20 03:49:57
【问题描述】:

我有一个 .yaws 文件,它从我编写的 authenticate 模块中调用 setup/0 函数,该模块已放在 ebin 目录中。当我从 Erlang shell 调用 authenticate:setup/0 时,它创建了一个表就好了,但是当我在浏览器中加载 something.yaws 时,它调用了 authenticate:setup/0 函数,它返回 {aborted,{bad_type,users,disc_copies,nonode@nohost}} (something.yaws 只是返回返回authenticate:setup/0 的值嵌入到 html 中用于调试目的)。

这是setup/0 函数:

setup() ->
    mnesia:create_schema([node()]),
    mnesia:start(),
    mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).

这是user 记录:

-record(user, {username, hashed_pw, salt}).

(在浏览器中尝试过之后,我尝试从 Erlang shell 调用它,所以不会干扰它。)

如果我运行yaws --mnesiadir /usr/local/lib/yaws-appmods/mnesia/,我会得到

Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:true]

Eshell V8.1  (abort with ^G)
1> 
=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Yaws: Using config file /etc/yaws/yaws.conf

=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Yaws: Using global subconfig file /etc/yaws/conf.d/localhost.conf

=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Ctlfile : /home/username/.yaws/yaws/default/CTL

=INFO REPORT==== 7-Nov-2016::00:04:49 ===
Yaws: Listening to 0.0.0.0:8080 for <1> virtual servers:
 - http://localhost:8080 under /usr/share/yaws/www
rd(user, {username, hashed_pw, salt}).
user
2> mnesia:create_schema([node()]), mnesia:start(), mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).
{aborted,{bad_type,users,disc_copies,nonode@nohost}}

如果我在以erl -mnesia dir '"/usr/local/lib/yaws-appmods/mnesia/"' 开头的 Erlang shell 中运行相同的 erlang 代码,它就可以正常工作。

【问题讨论】:

    标签: web erlang mnesia yaws erlang-shell


    【解决方案1】:

    当你运行 Yaws 时,传递命令行选项 --mnesiadir dir 告诉它你希望它在哪里存储 mnesia 数据。选项的dir 参数应该是您希望数据所在目录的路径名。例如,传递--mnesiadir /tmp 将导致Yaws 将mnesia 数据存储在/tmp 目录中。

    顺便说一句,如果你传递一个 mnesia dir 选项,将 mnesia 数据目录设置为不存在的东西,你可以在没有 Yaws 的 Erlang shell 中看到同样的错误:

    $ erl -mnesia dir '"/xyzfoo"'
    Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false]
    
    Eshell V8.1  (abort with ^G)
    1> rd(user, {username, hashed_pw, salt}).
    user
    2> mnesia:create_schema([node()]), mnesia:start(), mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).
    {aborted,{bad_type,users,disc_copies,nonode@nohost}}
    

    在这里,我们假设没有这样的目录/xyzfoo。第一个 Erlang shell 命令定义了您正在使用的相同 user 记录,第二个命令执行与您的 authenticate:setup/0 函数相同的步骤。如图所示,它返回与 Yaws 相同的错误。

    请注意,此处显示的目录名称 '"/xyzfoo"' 的不寻常引用对于将选项正确传递给 Erlang shell(无论如何,在典型的基于 UNIX 的系统上)是必需的,对于 Yaws --mnesiadir 不是必需的选项。另请注意,Erlang 选项是一个连字符,后跟两个单词 mnesia 和 dir,后跟引用的目录名称,而对于 Yaws,选项是一个单词 mnesiadir,前跟两个连字符,后跟一个普通的目录名。

    编辑:如果在为 Yaws 设置 mnesia 目录后你仍然看到问题,那是因为你试图在 mnesia 已经运行之后创建你的模式。当 Yaws 看到 --mnesiadir 选项时,它会启动 mnesia 应用程序。因此,您应该在运行 Yaws 之前创建模式,或者在创建模式之前停止 mnesia。将您的 authenticate:setup/0 函数更改为以下内容,它将在 Yaws 上运行:

    setup() ->
        mnesia:stop(),
        mnesia:create_schema([node()]),
        mnesia:start(),
        mnesia:create_table(users, [{type, set}, {record_name, user}, {disc_copies, [node()]}, {attributes, record_info(fields, user)}]).
    

    【讨论】:

    • 我尝试了yaws --mnesiadir DIR,它仍然给了我原来的错误,即使它应该有效,然后我尝试了erl -mnesia dir '"DIR"',它确实有效(DIR 在两种情况下都代表同一个目录)。 yaws 的输出不适合评论,所以我将其编辑到我的主要帖子中。
    猜你喜欢
    • 2014-07-28
    • 2013-04-02
    • 1970-01-01
    • 2017-01-01
    • 2016-10-04
    • 2012-05-29
    • 2015-11-17
    • 2011-04-14
    • 2014-06-06
    相关资源
    最近更新 更多