Mochiweb中有状态变量吗



我浏览了Mochiweb代码,但没有发现State变量的任何符号。

Mochiweb中是否存在类似于gen_server的State变量的内容?

我需要在服务器上存储少量与状态相关的服务器端(与会话无关)数据,我不想为此使用ETS或Mnesia。

我认为您对gen_server状态有点误解。

首先,让我简单解释一下mochiweb是如何工作的

Mochiweb不会为每个客户端生成一个gen_server进程。相反,它只是使用proc_lib:spawn/3生成一个新的进程,并创建一个参数化模块,基本上是以下类型的元组:

{mochiweb_request, #Port<0.623>, get, "/users", {1, 1}, []}

哪个是

{mochiweb_request, Socket, Method, RawPath, HTTPVersion, Headers}

此元组用作函数的参数,该函数作为循环参数传递给mochiweb_http:start/1。因此,当这个"循环"函数被调用时,它将看起来像这样:

handle_request(Req) ->
    %% The pattern matching below just shows what Req really is
    {mochiweb_request, _, _, _, _, _} = Req,
    ...

现在,来解释gen_server状态

基本上,gen_server是一个大致具有以下结构的进程。当然,IRL更复杂,但这应该会给你一个大致的想法:

init(Options)
    State = ...
    loop(Module, State).
loop(Module, State)
    NewState = receive
        {call, Msg, From} -> Module:handle_call(Msg, From, State)
        {cast, Msg} -> Module:handle_cast(Msg, State)
        Info -> Module:handle_info(Info, State)
    end,
    loop(Module, NewState).

所以,state只是一个参数,您可以在所有函数调用中拖动它,并在循环中进行更改。实际上,您的进程是否是一个gen_server并不重要,它没有它的生存期。在以下示例中,术语[1, 2, 3]也是一种状态:

a() ->
    b([1, 2, 3], now()).
b(State, Timestamp) ->
    Result = do_something(Timestamp)
    c(State, Result).
c(State, Payload) ->
    exit({State, Payload}).

现在,回到mochiweb

如果你需要创建自己的状态,你可以添加一个额外的函数参数:

handle_request(Req) ->
    User = Req:get(path),
    UserData = load_user_data(User),
    handle_request(Req, UserData).
handle_request(Req, UserData) ->
    ...

现在UserData也是一个状态。您可以循环这个过程,或者让它立即响应并结束——但只要您将UserData作为参数传递,就不会丢失它。

最后,如果您真的想让这个进程成为一个gen_server(在大多数情况下这确实是不合理的),您可以使用gen_server:enter_loop/3函数,使您的当前进程成为gen_server。这个函数的第三个参数将是您的状态,它将存储在启动的gen_server中。

相关内容

  • 没有找到相关文章

最新更新