我编写了一个gen_server模块(data_cahe.erl),它将把数据保存在ETS中。
我的代码如下:
-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(可以访问Email和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(...)根本没有经历过。如果有人抛出一些错误的话会非常感激。
答案 0 :(得分:3)
也许你拼写错了? data_cahe
代替d data_cache
..
答案 1 :(得分:3)
作为一般规则,您不希望将服务器的用户公开给gen_server
API。或者更具体地说,您不希望它们调用gen_server:call( ModuleName, {SomeAtom, And, DifferentArguments})
,因为它会为许多错误创建空间(错误拼写和消息元组中缺少“参数”)。而且很难找到你如何与这个服务器进行交互(人们必须调查handle_call
和handle_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,
更容易阅读,更难破解。