[연습] 간단한 이름 서비스
9057 단어 서비스
보주는 간단해. 시동gen서버 local 서비스 이름을 등록하면 인용하기 편합니다
그리고 사전을 State에 넣고 조회 등 서비스를 제공합니다.
코드는 다음과 같습니다.
%% @author cc fairjm
%% @doc @todo Add description to naming.
-module(naming).
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
%% ====================================================================
%% API functions
%% ====================================================================
-export([start/0,stop/0,insert/2,remove/1,lookup/1]).
-define(SERVER,?MODULE).
%% ====================================================================
%% Behavioural functions
%% ====================================================================
-record(state, {dic}).
start() ->
gen_server:start_link({local,?SERVER}, ?MODULE, [], []).
insert(Key,Value) ->
gen_server:cast(?SERVER,{insert,{Key,Value}})
.
remove(Key) ->
gen_server:cast(?SERVER, {remove,Key}).
lookup(Key)->
gen_server:call(?SERVER, {lookup,Key}).
stop() ->
gen_server:cast(?SERVER, stop).
%% init/1
%% ====================================================================
%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:init-1">gen_server:init/1</a>
-spec init(Args :: term()) -> Result when
Result :: {ok, State}
| {ok, State, Timeout}
| {ok, State, hibernate}
| {stop, Reason :: term()}
| ignore,
State :: term(),
Timeout :: non_neg_integer() | infinity.
%% ====================================================================
init([]) ->
{ok, #state{dic=dict:new()}}.
%% handle_call/3
%% ====================================================================
%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:handle_call-3">gen_server:handle_call/3</a>
-spec handle_call(Request :: term(), From :: {pid(), Tag :: term()}, State :: term()) -> Result when
Result :: {reply, Reply, NewState}
| {reply, Reply, NewState, Timeout}
| {reply, Reply, NewState, hibernate}
| {noreply, NewState}
| {noreply, NewState, Timeout}
| {noreply, NewState, hibernate}
| {stop, Reason, Reply, NewState}
| {stop, Reason, NewState},
Reply :: term(),
NewState :: term(),
Timeout :: non_neg_integer() | infinity,
Reason :: term().
%% ====================================================================
handle_call({lookup,Key}, _From, State) ->
#state{dic=Dic}=State,
case dict:find(Key, Dic) of
{ok,Value}->{reply, {ok,Value}, State};
_->{reply,{not_found},State}
end.
%% handle_cast/2
%% ====================================================================
%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:handle_cast-2">gen_server:handle_cast/2</a>
-spec handle_cast(Request :: term(), State :: term()) -> Result when
Result :: {noreply, NewState}
| {noreply, NewState, Timeout}
| {noreply, NewState, hibernate}
| {stop, Reason :: term(), NewState},
NewState :: term(),
Timeout :: non_neg_integer() | infinity.
%% ====================================================================
handle_cast({insert,{Key,Value}}, State) ->
#state{dic=Dic}=State,
{noreply, State#state{dic=dict:append(Key, Value,Dic )}};
handle_cast({remove,Key}, State) ->
#state{dic=Dic}=State,
{noreply, State#state{dic=dict:erase(Key, Dic)}};
handle_cast(stop, State) ->
{stop,{normal},State}.
%% handle_info/2
%% ====================================================================
%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:handle_info-2">gen_server:handle_info/2</a>
-spec handle_info(Info :: timeout | term(), State :: term()) -> Result when
Result :: {noreply, NewState}
| {noreply, NewState, Timeout}
| {noreply, NewState, hibernate}
| {stop, Reason :: term(), NewState},
NewState :: term(),
Timeout :: non_neg_integer() | infinity.
%% ====================================================================
handle_info(_Info, State) ->
{noreply, State}.
%% terminate/2
%% ====================================================================
%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:terminate-2">gen_server:terminate/2</a>
-spec terminate(Reason, State :: term()) -> Any :: term() when
Reason :: normal
| shutdown
| {shutdown, term()}
| term().
%% ====================================================================
terminate(_Reason, _State) ->
ok.
%% code_change/3
%% ====================================================================
%% @doc <a href="http://www.erlang.org/doc/man/gen_server.html#Module:code_change-3">gen_server:code_change/3</a>
-spec code_change(OldVsn, State :: term(), Extra :: term()) -> Result when
Result :: {ok, NewState :: term()} | {error, Reason :: term()},
OldVsn :: Vsn | {down, Vsn},
Vsn :: term().
%% ====================================================================
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%% ====================================================================
%% Internal functions
%% ====================================================================
사실 코드를 조금만 쓰면 돼요. 어랑의 코드가 간단명료해요.
호출은 다음과 같습니다.
(cc@dell-PC)8> c("naming").
{ok,naming}
(cc@dell-PC)9> naming:stop().
ok
(cc@dell-PC)10> naming:lookup(cc).
** exception exit: {noproc,{gen_server,call,[naming,{lookup,cc}]}}
in function gen_server:call/2 (gen_server.erl, line 180)
(cc@dell-PC)11> c("naming").
{ok,naming}
(cc@dell-PC)12> naming:start().
{ok,<0.68.0>}
(cc@dell-PC)13> naming:insert(cc,"hello").
ok
(cc@dell-PC)14> naming:lookup(cc).
{ok,["hello"]}
(cc@dell-PC)15> naming:remove(cc).
ok
(cc@dell-PC)16> naming:lookup(cc).
{not_found}
(cc@dell-PC)17> naming:stop().
** exception exit: {normal}
(cc@dell-PC)18>
=ERROR REPORT==== 12-Aug-2013::02:27:17 ===
** Generic server naming terminating
** Last message in was {'$gen_cast',stop}
** When Server state == {state,{dict,0,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],
[],[],[]},
{{[],[],[],[],[],[],[],[],[],[],[],[],[],
[],[],[]}}}}
** Reason for termination ==
** {normal}
(cc@dell-PC)18> naming:lookup(cc).
** exception exit: {noproc,{gen_server,call,[naming,{lookup,cc}]}}
in function gen_server:call/2 (gen_server.erl, line 180)
원격에서도 rpc를 호출할 수 있습니다.
(cc02@dell-PC)1> net_adm:ping('cc@dell-PC').
pong
(cc02@dell-PC)2> rpc:call('cc@dell-PC',naming,lookup,cc).
{badrpc,{'EXIT',{badarg,[{erlang,apply,
[naming,lookup,cc],
[]},
{rpc,'-handle_call_call/6-fun-0-',5,
[{file,"rpc.erl"},{line,205}]}]}}}
(cc02@dell-PC)3> rpc:call('cc@dell-PC',naming,lookup,[cc]).
{badrpc,{'EXIT',{noproc,{gen_server,call,
[naming,{lookup,cc}]}}}}
(cc02@dell-PC)4> rpc:call('cc@dell-PC',naming,lookup,[cc]).
{ok,["hello","hello2"]}
(cc02@dell-PC)5> rpc:call('cc@dell-PC',naming,lookup,[cc]).
{ok,["hello","hello2"]}
(cc02@dell-PC)6> rpc:call('cc@dell-PC',naming,lookup,[cc]).
{ok,["hello","hello2"]}
(cc02@dell-PC)7> rpc:call('cc@dell-PC',naming,lookup,[cc]).
{not_found}
(cc02@dell-PC)8> rpc:call('cc@dell-PC',naming,lookup,[cc]).
{badrpc,{'EXIT',{noproc,{gen_server,call,
[naming,{lookup,cc}]}}}}
(cc02@dell-PC)9>
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
FutureVuls : JPCERT, US-CERT의 주의 환기에 대해이 기사는 의 20 일째 기사입니다. 오늘 이외는 모두 씨가 쓰고 있습니다. FutureVuls에 대한 개요는 에서 확인할 수 있습니다. 이번에는 FutureVuls의 취약성으로 보이는 경계 정보에 대해 설명합니다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.