【问题标题】:Erlang's dets doesn't create file with open_fileErlang 的 dets 不使用 open_file 创建文件
【发布时间】:2017-05-01 16:15:57
【问题描述】:

这是我第一次尝试用 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”文件。为什么?

【问题讨论】:

    标签: erlang dets


    【解决方案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/

    【讨论】:

      猜你喜欢
      • 2011-06-09
      • 2010-12-18
      • 1970-01-01
      • 2017-08-11
      • 2011-08-06
      • 2015-04-18
      • 1970-01-01
      • 2014-03-29
      • 2010-12-18
      相关资源
      最近更新 更多