blob: e5c9cf97e1c36e9c114fd476b1ee4bee4da0d2e5 [file] [log] [blame]
David Reissac549552008-06-10 22:56:59 +00001%%%-------------------------------------------------------------------
2%%% File : thrift_server.erl
3%%% Author : <todd@lipcon.org>
4%%% Description :
5%%%
6%%% Created : 28 Jan 2008 by <todd@lipcon.org>
7%%%-------------------------------------------------------------------
8-module(thrift_server).
9
10-behaviour(gen_server).
11
12%% API
David Reissc308d692008-06-11 00:56:25 +000013-export([start_link/3, stop/1]).
David Reissac549552008-06-10 22:56:59 +000014
15%% gen_server callbacks
16-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
17 terminate/2, code_change/3]).
18
19-define(SERVER, ?MODULE).
20
21-record(state, {listen_socket, acceptor, service}).
David Reissac549552008-06-10 22:56:59 +000022
23%%====================================================================
24%% API
25%%====================================================================
26%%--------------------------------------------------------------------
27%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
28%% Description: Starts the server
29%%--------------------------------------------------------------------
30start_link(Port, Service, HandlerModule) when is_integer(Port), is_atom(HandlerModule) ->
31 gen_server:start_link({local, ?SERVER}, ?MODULE, {Port, Service, HandlerModule}, []).
32
David Reissc308d692008-06-11 00:56:25 +000033
34%%--------------------------------------------------------------------
35%% Function: stop(Pid) -> ok, {error, Reason}
36%% Description: Stops the server.
37%%--------------------------------------------------------------------
38stop(Pid) when is_pid(Pid) ->
39 gen_server:call(Pid, stop).
40
41
David Reissac549552008-06-10 22:56:59 +000042%%====================================================================
43%% gen_server callbacks
44%%====================================================================
45
46%%--------------------------------------------------------------------
47%% Function: init(Args) -> {ok, State} |
48%% {ok, State, Timeout} |
49%% ignore |
50%% {stop, Reason}
51%% Description: Initiates the server
52%%--------------------------------------------------------------------
David Reiss1c1ca742008-06-10 22:57:21 +000053init({Port, Service, Handler}) ->
David Reissac549552008-06-10 22:56:59 +000054 {ok, Socket} = gen_tcp:listen(Port,
55 [binary,
56 {packet, 0},
57 {active, false},
58 {nodelay, true},
59 {reuseaddr, true}]),
60 Acceptor = spawn_link(fun () -> acceptor(Socket, Service, Handler) end),
61 {ok, #state{listen_socket = Socket,
62 acceptor = Acceptor,
63 service = Service}}.
64
65%%--------------------------------------------------------------------
66%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
67%% {reply, Reply, State, Timeout} |
68%% {noreply, State} |
69%% {noreply, State, Timeout} |
70%% {stop, Reason, Reply, State} |
71%% {stop, Reason, State}
72%% Description: Handling call messages
73%%--------------------------------------------------------------------
David Reissc308d692008-06-11 00:56:25 +000074handle_call(stop, _From, State) ->
75 State#state.acceptor ! stop,
76 {stop, stopped, ok, State}.
David Reissac549552008-06-10 22:56:59 +000077
78%%--------------------------------------------------------------------
79%% Function: handle_cast(Msg, State) -> {noreply, State} |
80%% {noreply, State, Timeout} |
81%% {stop, Reason, State}
82%% Description: Handling cast messages
83%%--------------------------------------------------------------------
84handle_cast(_Msg, State) ->
85 {noreply, State}.
86
87%%--------------------------------------------------------------------
88%% Function: handle_info(Info, State) -> {noreply, State} |
89%% {noreply, State, Timeout} |
90%% {stop, Reason, State}
91%% Description: Handling all non call/cast messages
92%%--------------------------------------------------------------------
93handle_info(_Info, State) ->
94 {noreply, State}.
95
96%%--------------------------------------------------------------------
97%% Function: terminate(Reason, State) -> void()
98%% Description: This function is called by a gen_server when it is about to
99%% terminate. It should be the opposite of Module:init/1 and do any necessary
100%% cleaning up. When it returns, the gen_server terminates with Reason.
101%% The return value is ignored.
102%%--------------------------------------------------------------------
103terminate(_Reason, _State) ->
104 ok.
105
106%%--------------------------------------------------------------------
107%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
108%% Description: Convert process state when code is changed
109%%--------------------------------------------------------------------
110code_change(_OldVsn, State, _Extra) ->
111 State#state.acceptor ! refresh,
112 {ok, State}.
113
114%%--------------------------------------------------------------------
115%%% Internal functions
116%%--------------------------------------------------------------------
117
118acceptor(ListenSocket, Service, Handler)
David Reiss1c1ca742008-06-10 22:57:21 +0000119 when is_port(ListenSocket), is_atom(Handler) ->
David Reissac549552008-06-10 22:56:59 +0000120 {ok, Socket} = gen_tcp:accept(ListenSocket),
121 error_logger:info_msg("Accepted client"),
122
David Reiss90b40832008-06-10 22:58:52 +0000123 {ok, SocketTransport} = thrift_socket_transport:new(Socket),
124 {ok, BufferedTransport} = thrift_buffered_transport:new(SocketTransport),
125 {ok, Protocol} = thrift_binary_protocol:new(BufferedTransport),
David Reissac549552008-06-10 22:56:59 +0000126
127 thrift_processor:start(Protocol, Protocol, Service, Handler),
128 receive
129 refresh ->
130 error_logger:info_msg("Acceptor refreshing~n"),
David Reissc308d692008-06-11 00:56:25 +0000131 ?MODULE:acceptor(ListenSocket, Service, Handler);
132 stop ->
133 ok
David Reissac549552008-06-10 22:56:59 +0000134 after 0 -> acceptor(ListenSocket, Service, Handler)
135 end.