blob: 5760e1cfb855331cccbd5ed086cd5fab6dc91f72 [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
13-export([start_link/3]).
14
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
33%%====================================================================
34%% gen_server callbacks
35%%====================================================================
36
37%%--------------------------------------------------------------------
38%% Function: init(Args) -> {ok, State} |
39%% {ok, State, Timeout} |
40%% ignore |
41%% {stop, Reason}
42%% Description: Initiates the server
43%%--------------------------------------------------------------------
David Reiss1c1ca742008-06-10 22:57:21 +000044init({Port, Service, Handler}) ->
David Reissac549552008-06-10 22:56:59 +000045 {ok, Socket} = gen_tcp:listen(Port,
46 [binary,
47 {packet, 0},
48 {active, false},
49 {nodelay, true},
50 {reuseaddr, true}]),
51 Acceptor = spawn_link(fun () -> acceptor(Socket, Service, Handler) end),
52 {ok, #state{listen_socket = Socket,
53 acceptor = Acceptor,
54 service = Service}}.
55
56%%--------------------------------------------------------------------
57%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
58%% {reply, Reply, State, Timeout} |
59%% {noreply, State} |
60%% {noreply, State, Timeout} |
61%% {stop, Reason, Reply, State} |
62%% {stop, Reason, State}
63%% Description: Handling call messages
64%%--------------------------------------------------------------------
65handle_call(_Request, _From, State) ->
66 Reply = ok,
67 {reply, Reply, State}.
68
69%%--------------------------------------------------------------------
70%% Function: handle_cast(Msg, State) -> {noreply, State} |
71%% {noreply, State, Timeout} |
72%% {stop, Reason, State}
73%% Description: Handling cast messages
74%%--------------------------------------------------------------------
75handle_cast(_Msg, State) ->
76 {noreply, State}.
77
78%%--------------------------------------------------------------------
79%% Function: handle_info(Info, State) -> {noreply, State} |
80%% {noreply, State, Timeout} |
81%% {stop, Reason, State}
82%% Description: Handling all non call/cast messages
83%%--------------------------------------------------------------------
84handle_info(_Info, State) ->
85 {noreply, State}.
86
87%%--------------------------------------------------------------------
88%% Function: terminate(Reason, State) -> void()
89%% Description: This function is called by a gen_server when it is about to
90%% terminate. It should be the opposite of Module:init/1 and do any necessary
91%% cleaning up. When it returns, the gen_server terminates with Reason.
92%% The return value is ignored.
93%%--------------------------------------------------------------------
94terminate(_Reason, _State) ->
95 ok.
96
97%%--------------------------------------------------------------------
98%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
99%% Description: Convert process state when code is changed
100%%--------------------------------------------------------------------
101code_change(_OldVsn, State, _Extra) ->
102 State#state.acceptor ! refresh,
103 {ok, State}.
104
105%%--------------------------------------------------------------------
106%%% Internal functions
107%%--------------------------------------------------------------------
108
109acceptor(ListenSocket, Service, Handler)
David Reiss1c1ca742008-06-10 22:57:21 +0000110 when is_port(ListenSocket), is_atom(Handler) ->
David Reissac549552008-06-10 22:56:59 +0000111 {ok, Socket} = gen_tcp:accept(ListenSocket),
112 error_logger:info_msg("Accepted client"),
113
114 {ok, Transport} = thrift_socket_transport:new(Socket),
115 {ok, Protocol} = thrift_binary_protocol:new(Transport),
116
117 thrift_processor:start(Protocol, Protocol, Service, Handler),
118 receive
119 refresh ->
120 error_logger:info_msg("Acceptor refreshing~n"),
121 ?MODULE:acceptor(ListenSocket, Service, Handler)
122 after 0 -> acceptor(ListenSocket, Service, Handler)
123 end.