Mochiwebコードをざっと調べましたが、State変数の兆候は見つかりませんでした。
gen_serverのState変数に似たものがMochiwebに存在しますか?
状態に関連するサーバー側(セッションに関連しない)のデータをサーバーに少量保存する必要がありますが、そのためにETSやMnesiaを使用したくありません。
Mochiwebコードをざっと調べましたが、State変数の兆候は見つかりませんでした。
gen_serverのState変数に似たものがMochiwebに存在しますか?
状態に関連するサーバー側(セッションに関連しない)のデータをサーバーに少量保存する必要がありますが、そのために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にするgen_server:enter_loop/3関数を使用できます。そして、この関数の3番目の引数は、開始されたgen_server内に格納される状態になります。