Erlang的dets不会使用open_file

时间:2016-12-15 22:58:09

标签: erlang dets

这是我第一次尝试在Erlang中编写任何东西,所以也许问题很愚蠢。

我正在使用牛仔编写一个非常简单的HTTP服务器

db_name() -> "DB_test".

timestamp() ->
    calendar:datetime_to_gregorian_seconds(calendar:universal_time()).

sha(Str) ->
    <<X:256/big-unsigned-integer>> = crypto:hash(sha256, Str),
    lists:flatten(io_lib:format("~64.16.0b", [X])).

handle_post(Req0, State) -> 
    Link = binary_to_list(cowboy_req:header(<<"link">>, Req0)),
    dets:open_file(db_name(), []),
    dets:insert(db_name(), {hashed_url(Link), Link, timestamp()}),

    Req = cowboy_req:reply(200,
        #{<<"content-type">> => <<"text/plain">>},
        sha(Link),
        Req0),
    {ok, Req, State}.

这个想法是POST HTTP请求包含一个带有链接的“链接”标题。收到此类请求后,我的服务器应将其哈希值与链接及其时间戳一起存储在dets表中。问题是没有创建“DB_test”文件。为什么呢?

1 个答案:

答案 0 :(得分:1)

根据您的示例代码,很难确切地说明原因,因为您忽略了两个dets的返回值:open_file / 2和dets:insert / 2。 它们都为成功和失败案例返回不同的值;但不要抛出异常。 有关详细信息,请参阅官方文档:http://erlang.org/doc/man/dets.html

最简单的解决方案是在非成功案例中崩溃牛仔连接处理流程。您可以通过执行以下操作来执行此操作:

 {ok, Ref} = dets:open_file(db_name(), []),
 ok = dets:insert(Ref, {hashed_url(Link), Link, timestamp()}),

如果返回的值无法与语句的左侧模式匹配,则会在失败的情况下因badmatch异常而崩溃,从而导致牛仔将HTTP 500返回给客户端。 然后,您将看到有关堆栈跟踪记录中实际错误的详细信息

第二种解决方案是明确处理失败案例,您可以使用'case'关键字。 一个例子是:

case dets:open_file(db_name(), []) of
   {ok, Ref} ->
       do_success_things();
   {error, Reason}=E ->
       io:format("Unable to open database file: ~p~n", [E]),
       do_failure_things();
end

为了进一步阅读,我强烈推荐在函数和错误和异常章节中学习一些Erlang以获得很好的效果:http://learnyousomeerlang.com/ < / p>