1

ETS にデータを保存する gen_server モジュール (data_cahe.erl) を作成しました。

私のコードは次のとおりです。

-export([start_link/0]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
 terminate/2, code_change/3]).

-define(SERVER, ?MODULE).
-define(TABLE_ID, ?MODULE).
-record(state, {user_id, my_reading, my_status}).

start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

init([]) ->
{ok, ?TABLE_ID} = new_cache(?TABLE_ID),
{ok, #state{user_id=undefined, my_reading=undefined, my_status=undefined}}.

handle_call:

handle_call({save, UserId, Readings}, _From, _Status) ->
io:format("Inside handle_call_save: ~n~p~n",[]);
%Check if email is present
case my_reading(UserId) of
{error, not_found} -> %%Email not present
    io:format("Inside handle_call_save Just before save: ~n~p~n",[]),
    Result = save_my_readings(UserId, Readings),
    {reply, ok, #state{user_id=UserId, my_reading=Readings, my_status=Result}};
{ok, Reading} ->
    io:format("Inside handle_call_save Just before delete and save: ~n~p~n",[]),
    delete_my_reading(UserId), %%delete last reading
    Result = save_my_readings(UserId, Readings), %%Save this new Reading
    {reply, ok, #state{user_id=UserId, my_reading=Readings, my_status=Result}}
end;

このhandel_call(EメールとAccessTokenにアクセスできる)を使用して、ワーカーモジュールからETSにデータを保存しようとしています:

case my_app_interface:get_data_summary(binary_to_list(AccessToken)) of
    {error, _Reason1} ->
    %%Start a new Timer Cycle
    ..
    ..
    Readings1 ->
        gen_server:call(data_cahe, {save, Email, Readings1}), %%HERE IT CRASHES
        io:format("Get Data Summary : ~n~p~n",[Readings1]) %%This is printed when the line above is commented
 end,

ただし、gen_server:call(...) はクラッシュします。この行をコメントアウトすると、読み値が通常の順序で出力されます。

handle_call メソッドの print ステートメントを除くすべての行をコメントアウトしましたが、何も出力されません。gen_server:call(...) がまったく通っていないようです。誰かが何がうまくいかないのかを明らかにしてくれたら、非常にありがたいです。

4

2 に答える 2

3

多分あなたはそれを間違って綴った?data_cahedの代わりにdata_cache..

于 2014-10-28T22:49:10.077 に答える
3

原則として、サーバーのユーザーをgen_serverAPI に公開することは望ましくありません。gen_server:call( ModuleName, {SomeAtom, And, DifferentArguments})または、より具体的には、多くのエラー (スペルミスやメッセージタプルの「引数」の欠落) のためのスペースが作成されるため、呼び出したくない場合があります。また、このサーバーと対話する方法を見つけるのが難しくなります ( と を調べる必要がありますがhandle_callhandle_castこれは最も簡単な方法ではありません)。

これを回避するには、そのようなすべての相互作用 (すべての可能な呼び出しとキャスト) を関数呼び出しでラップする必要があります。そして、これらの関数はモジュール インターフェイスとして公開 (エクスポート) されます。そして最終的に、クライアントはそれが実装されていることを知る必要さえありませんgen_server

したがって、モジュールが呼び出されdata_cache、データを保存する機能がある場合は、関数を実装するだけsaveです。

save( Email, Readings) ->
   gen_server:call(?SERVER, {save, Email, Readings1}).

マクロも使用?SERVERしました (スペルミスの可能性を少し助けるため)。そのままhandle_callにしておくことができます。これで、クライアント呼び出しを次のように変更できます

    Readings1 ->
        data_cache:save(Email, Readings1),
        io:format("Get Data Summary : ~n~p~n",[Readings1]) %%This is printed when the line above is commented
 end,

これははるかに読みやすく、壊れにくいです。

于 2014-10-28T23:03:08.510 に答える