forked from Angra-DB/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.erl
More file actions
109 lines (81 loc) · 2.72 KB
/
server.erl
File metadata and controls
109 lines (81 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
% ------------------------------------------------
% @author Rodrigo Bonifacio <rbonifacio@unb.br>
%
% @doc a first attempt to build the Angra-DB server
%
% @end
% ------------------------------------------------
-module(server).
-behavior(gen_server).
%
% API functions
%
-export([ start_link/1
, start_link/0
, get_count/0 % we can understand both get_count and stop as adm operations
, stop/0]).
% gen_server callbacks
-export([ init/1
, handle_call/3
, handle_cast/2
, handle_info/2
, terminate/2
, code_change/3]).
-define(SERVER, ?MODULE). % declares a SERVER macro constant (?MODULE is the module's name)
-define(DEFAULT_PORT, 1234). % declares a DEFAULT_PORT macro constant
-record(state, {port, lsock, request_count = 0}). % a record for keeping the server state
%%%======================================================
%%% API
%%%
%%% Each one of the functions that appear in the
%%% API section, calls one of the gen_server library
%%% functions (start_link/4, call/2, cast/2)... This
%%% is a bit trick.
%%%======================================================
start_link(Port) ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [Port], []).
start_link() ->
start_link(?DEFAULT_PORT).
get_count() ->
gen_server:call(?SERVER, get_count).
stop() ->
gen_server:cast(?SERVER, stop).
%%%===========================================
%%% gen_server callbacks
%%%===========================================
init([Port]) ->
{ok, LSock} = gen_tcp:listen(Port, [{active, true}]),
{ok, #state{port = Port, lsock = LSock}, 0}.
handle_call(get_count, _From, State) ->
{reply, {ok, State#state.request_count}, State}.
handle_cast(stop, State) ->
{stop, normal, State}.
handle_info({tcp, Socket, RawData}, State) ->
process_request(Socket, RawData),
RequestCount = State#state.request_count,
{noreply,State#state{request_count = RequestCount + 1}};
handle_info(timeout, #state{lsock = LSock} = State) ->
{ok, _Sock} = gen_tcp:accept(LSock),
{noreply, State}.
terminate(_Reason, _State) ->
ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
process_request(Socket, RawData) ->
try
% [Cmd|Args] = parse(RawData),
% io:format("~p~n", [Cmd|Args]),
Pid = spawn(interpreter, execute, []),
Pid ! {self(), {[save, 1, rbonifacio]}},
receive
{_From, ok} -> gen_tcp:send(Socket, io_lib:fwrite("~p~n", ["ok"]))
end
catch
_Class:Err -> gen_tcp:send(Socket, io_lib:fwrite("~p~n", [Err]))
end.
parse(RawData) ->
Tokens = string:tokens(RawData, " "),
case Tokens of
[save|[Key|Doc]] -> [save|[Key|(string:join(Doc, " "))]];
[lookup,Key] -> [lookup|Key]
end.