Mnesia 在 Yaws 运行 时无法创建表,但在 Erlang shell 运行 时可以
Mnesia can't create tables when ran by Yaws, but can when ran from the Erlang shell
我有一个 .yaws 文件,它调用我编写的 authenticate
模块中的 setup/0
函数,我将其放在 ebin
目录中。当我从 Erlang shell 调用 authenticate:setup/0
时,它会创建一个 table 就好了,但是当我在浏览器中加载 something.yaws 时,它会调用 authenticate:setup/0
函数,它 returns {aborted,{bad_type,users,disc_copies,nonode@nohost}}
(something.yaws 只是 returns 嵌入 html 的 authenticate:setup/0
的 return 值用于调试目的) .
这是 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}}
如果我 运行 Erlang shell 中的相同 erlang 代码以 erl -mnesia dir '"/usr/local/lib/yaws-appmods/mnesia/"'
开头,它工作得很好。
当你 运行 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
函数相同的步骤。如图所示,它 returns 与您在 Yaws 中看到的错误相同。
请注意,此处显示的目录名称 '"/xyzfoo"'
的不寻常引号是将选项正确传递给 Erlang shell 所必需的(无论如何,在典型的基于 UNIX 的系统上),是' Yaws --mnesiadir
选项不需要。另请注意,Erlang 选项是一个连字符后跟两个单词 mnesia
和 dir
,然后是引用的目录名称,而对于 Yaws,选项是一个单词 mnesiadir
前面是两个连字符,后跟一个普通的目录名称。
编辑:如果在为 Yaws 设置 mnesia 目录后您仍然遇到问题,那是因为您试图在 mnesia 已经 运行ning 之后创建您的模式。当 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 文件,它调用我编写的 authenticate
模块中的 setup/0
函数,我将其放在 ebin
目录中。当我从 Erlang shell 调用 authenticate:setup/0
时,它会创建一个 table 就好了,但是当我在浏览器中加载 something.yaws 时,它会调用 authenticate:setup/0
函数,它 returns {aborted,{bad_type,users,disc_copies,nonode@nohost}}
(something.yaws 只是 returns 嵌入 html 的 authenticate:setup/0
的 return 值用于调试目的) .
这是 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}}
如果我 运行 Erlang shell 中的相同 erlang 代码以 erl -mnesia dir '"/usr/local/lib/yaws-appmods/mnesia/"'
开头,它工作得很好。
当你 运行 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
函数相同的步骤。如图所示,它 returns 与您在 Yaws 中看到的错误相同。
请注意,此处显示的目录名称 '"/xyzfoo"'
的不寻常引号是将选项正确传递给 Erlang shell 所必需的(无论如何,在典型的基于 UNIX 的系统上),是' Yaws --mnesiadir
选项不需要。另请注意,Erlang 选项是一个连字符后跟两个单词 mnesia
和 dir
,然后是引用的目录名称,而对于 Yaws,选项是一个单词 mnesiadir
前面是两个连字符,后跟一个普通的目录名称。
编辑:如果在为 Yaws 设置 mnesia 目录后您仍然遇到问题,那是因为您试图在 mnesia 已经 运行ning 之后创建您的模式。当 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)}]).