r1295@opsdev009 (orig r69995): cpiro | 2007-11-14 22:26:28 -0800
[amiethrift.git] / lib / erl / src / thrift_oop_server.erl
blob052578ceefb4bca92754bfec01f1603001714201
1 %%% Copyright (c) 2007- Facebook
2 %%% Distributed under the Thrift Software License
3 %%%
4 %%% See accompanying file LICENSE or visit the Thrift site at:
5 %%% http://developers.facebook.com/thrift/
7 %%%-------------------------------------------------------------------
8 %%% @doc
9 %%% @end
10 %%%-------------------------------------------------------------------
11 -module(thrift_oop_server).
13 -behaviour(gen_server).
14 %%--------------------------------------------------------------------
15 %% Include files
16 %%--------------------------------------------------------------------
17 -include("oop.hrl").
19 -include("thrift.hrl").
21 %%--------------------------------------------------------------------
22 %% External exports
23 %%--------------------------------------------------------------------
24 -export([
25 start_link/0,
26 stop/0
27 ]).
29 %%--------------------------------------------------------------------
30 %% gen_server callbacks
31 %%--------------------------------------------------------------------
32 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
34 %%--------------------------------------------------------------------
35 %% record definitions
36 %%--------------------------------------------------------------------
38 %%--------------------------------------------------------------------
39 %% macro definitions
40 %%--------------------------------------------------------------------
41 -define(SERVER, ?MODULE).
43 %%====================================================================
44 %% External functions
45 %%====================================================================
46 %%--------------------------------------------------------------------
47 %% @doc Starts the server.
48 %% @spec start_link() -> {ok, pid()} | {error, Reason}
49 %% @end
50 %%--------------------------------------------------------------------
51 start_link() ->
52 gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
54 %%--------------------------------------------------------------------
55 %% @doc Stops the server.
56 %% @spec stop() -> ok
57 %% @end
58 %%--------------------------------------------------------------------
59 stop() ->
60 gen_server:cast(?SERVER, stop).
62 %%====================================================================
63 %% Server functions
64 %%====================================================================
66 %%--------------------------------------------------------------------
67 %% Function: init/1
68 %% Description: Initiates the server
69 %% Returns: {ok, State} |
70 %% {ok, State, Timeout} |
71 %% ignore |
72 %% {stop, Reason}
73 %%--------------------------------------------------------------------
75 init({Class, Args}) ->
76 process_flag(trap_exit, true),
77 try
78 State = apply(Class, new, Args),
79 ?INFO("thrift ~p:new(~s) = ~s", [Class, thrift_utils:unbrack(Args), oop:inspect(State)]),
80 {ok, State}
81 catch
82 E -> {stop, {new_failed, E}}
83 end;
85 init(_) ->
86 {stop, invalid_params}.
88 %%--------------------------------------------------------------------
89 %% Function: handle_call/3
90 %% Description: Handling call messages
91 %% Returns: {reply, Reply, State} |
92 %% {reply, Reply, State, Timeout} |
93 %% {noreply, State} |
94 %% {noreply, State, Timeout} |
95 %% {stop, Reason, Reply, State} | (terminate/2 is called)
96 %% {stop, Reason, State} (terminate/2 is called)
97 %%--------------------------------------------------------------------
99 handle_call(Request, From, State) ->
100 handle_either(call, Request, From, State).
102 %%--------------------------------------------------------------------
103 %% Function: handle_cast/2
104 %% Description: Handling cast messages
105 %% Returns: {noreply, State} |
106 %% {noreply, State, Timeout} |
107 %% {stop, Reason, State} (terminate/2 is called)
108 %%--------------------------------------------------------------------
110 handle_cast(stop, State) ->
111 {stop, normal, State};
113 handle_cast({Method, Args}, State) ->
114 handle_either(cast, {Method, Args}, undefined, State).
116 -define(REPLY(Value, State),
117 case Type of
118 call -> {reply, Value, State};
119 cast -> {noreply, State}
123 handle_either(Type, Request, From, State) ->
124 %% error_logger:info_msg("~p: ~p", [?SERVER, oop:inspect(State)]),
125 %% error_logger:info_msg("handle_call(Request=~p, From=~p, State)", [Request, From]),
127 case Request of
128 {get, [Field]} ->
129 Value = oop:get(State, Field),
130 ?REPLY(Value, State);
132 {set, [Field, Value]} ->
133 State1 = oop:set(State, Field, Value),
134 ?REPLY(Value, State1);
136 {class, []} ->
137 ?REPLY(?CLASS(State), State);
139 {Method, Args} ->
140 handle_method(Type, State, Method, Args);
142 _ ->
143 error_logger:format("no match for Request = ~p", [Request]),
144 %% {stop, server_error, State}
145 {reply, server_error, State}
146 end.
148 handle_method(Type, State, Method, Args) ->
149 %% is an effectful call?
150 Is_effectful = lists:prefix("effectful_", atom_to_list(Method)),
151 Call = oop:call(State, Method, Args),
153 %% TODO(cpiro): maybe add error handling here? = catch oop:call?
155 case {Is_effectful, Call} of
156 {true, {Retval, State1}} ->
157 ?REPLY(Retval, State1);
159 {true, _MalformedReturn} ->
160 %% TODO(cpiro): bad match -- remove when we're done converting
161 error_logger:format("oop:call(effectful_*,..,..) malformed return value ~p",
162 [_MalformedReturn]),
163 %% {stop, server_error, State}
164 {noreply, State};
166 {false, Retval} ->
167 ?REPLY(Retval, State)
168 end.
170 %%--------------------------------------------------------------------
171 %% Function: handle_info/2
172 %% Description: Handling all non call/cast messages
173 %% Returns: {noreply, State} |
174 %% {noreply, State, Timeout} |
175 %% {stop, Reason, State} (terminate/2 is called)
176 %%--------------------------------------------------------------------
177 handle_info({'EXIT', Pid, Except} = All, State) ->
178 Result = try
179 oop:call(State, catches, [Pid, Except])
180 catch
181 exit:{missing_method, _} ->
182 unhandled
183 end,
185 case Result of
186 unhandled ->
187 error_logger:format("unhandled exit ~p", [All]),
188 {stop, All, State};
189 _WasHandled ->
190 {noreply, State}
191 end;
193 handle_info(Info, State) ->
194 error_logger:info_msg("~p", [Info]),
195 {noreply, State}.
197 %%--------------------------------------------------------------------
198 %% Function: terminate/2
199 %% Description: Shutdown the server
200 %% Returns: any (ignored by gen_server)
201 %%--------------------------------------------------------------------
202 terminate(Reason, State) ->
203 %%error_logger:format("~p terminated!: ~p", [self(), Reason]),
206 %%--------------------------------------------------------------------
207 %% Func: code_change/3
208 %% Purpose: Convert process state when code is changed
209 %% Returns: {ok, NewState}
210 %%--------------------------------------------------------------------
211 code_change(OldVsn, State, Extra) ->
212 {ok, State}.
214 %%====================================================================
215 %%% Internal functions
216 %%====================================================================