2014-10-28 26 views
1

我寫了一個gen_server模塊(data_cahe.erl),它將數據保存在ETS中。ERLang OTP gen_server:call()失敗

我的代碼如下:

-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(可以訪問電子郵件和的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:調用(...)崩潰。當我註釋掉這一行時,讀數按通常順序打印。

我甚至已經列出了除了handle_call方法中的print語句外的所有行 - 但沒有任何內容被打印。看起來gen_server:call(...)根本沒有經過。如果有人發出什麼問題,會非常感激。

+0

由於您的程序崩潰,如果包含錯誤消息,它會很好。 – mpm 2014-10-28 22:51:27

回答

3

也許你拼寫錯了嗎? data_cahe而不是d data_cache ..

+0

我的壞...謝謝.. – raich 2014-10-29 03:15:40

3

通常,您不希望將服務器的用戶公開到gen_server API。或者更具體地說,您不希望他們撥打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宏(以幫助可能misspelings一點),並且你可以離開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, 

這是更容易閱讀,更難以打破。

+0

感謝mpm爲您的輸入。真的很感激它! – raich 2014-10-29 03:17:29