Permalink
Browse files

message_store refatorado para usar o gen_server.

  • Loading branch information...
1 parent 3237f47 commit 2d86953d6bae9d4e43e3d5bc82d9657f3806063a @carlosbrando committed Mar 29, 2011
Showing with 269 additions and 51 deletions.
  1. +3 −3 message_router.erl
  2. +142 −48 message_store.erl
  3. +77 −0 message_store.old
  4. +47 −0 misc_server.erl
View
@@ -4,11 +4,11 @@
start () ->
server_util:start(?SERVER, {message_router, route_messages, [dict:new()]}),
- message_store:start().
+ message_store:start_link().
stop () ->
server_util:stop(?SERVER),
- message_store:stop().
+ message_store:shutdown().
send_chat_message (ClientName, MessageBody) ->
global:send(?SERVER, {send_chat_msg, ClientName, MessageBody}).
@@ -31,7 +31,7 @@ route_messages (Clients) ->
end,
route_messages(Clients);
{register_nick, ClientName, ClientPid} ->
- Messages = message_store:get_messages(ClientName),
+ Messages = message_store:find_messages(ClientName),
lists:foreach(fun(Msg) -> ClientPid ! {printmsg, Msg} end, Messages),
route_messages(dict:store(ClientName, ClientPid, Clients));
{unregister_nick, ClientName} ->
View
@@ -1,52 +1,152 @@
--module (message_store).
--compile(export_all).
+%%%-------------------------------------------------------------------
+%%% File: message_store.erl
+%%% @author Carlos Brando <eduardobrando@gmail.com> [http://www.nomedojogo.com]
+%%% @copyright 2011 Carlos Brando
+%%% @doc
+%%%
+%%% @end
+%%%
+%%% @since 2011-03-29 by Carlos Brando
+%%%-------------------------------------------------------------------
+-module(message_store).
+-author('eduardobrando@gmail.com').
+
+-behaviour(gen_server).
+
-include_lib("stdlib/include/qlc.hrl").
--define (SERVER, message_store).
+%% API
+-export([start_link/0, save_message/2, find_messages/1, shutdown/0]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+ terminate/2, code_change/3]).
+
+-define (SERVER, ?MODULE).
+
+-record(state, {}).
-record (chat_message, {addressee, body, created_on}).
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% @spec start_link() -> {ok,Pid} | ignore | {error,Error}
+%% @doc Starts the server
+%% @end
+%%--------------------------------------------------------------------
+start_link() ->
+ gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
+
save_message (Addressee, Body) ->
- global:send(?SERVER, {save_msg, Addressee, Body}).
+ gen_server:call(?SERVER, {save_msg, Addressee, Body}).
find_messages (Addressee) ->
- global:send(?SERVER, {find_msgs, Addressee, self()}),
- receive
+ case gen_server:call(?SERVER, {find_msgs, Addressee}) of
{ok, Messages} ->
Messages
end.
-start () ->
- server_util:start(?SERVER, {message_store, run, [true]}).
+shutdown () ->
+ gen_server:call(?SERVER, stop).
-stop () ->
- server_util:stop(?SERVER).
-
-run (FirstTime) ->
- if
- FirstTime == true ->
- init_store(),
- run(false);
- true ->
- receive
- {save_msg, Addressee, Body} ->
- store_message(Addressee, Body),
- run(FirstTime);
- {find_msgs, Addressee, Pid} ->
- Messages = get_messages(Addressee),
- Pid ! {ok, Messages},
- run(FirstTime);
- shutdown ->
- mnesia:stop(),
- io:format("Shutting down...~n")
- end
- end.
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
-delete_messages (Messages) ->
- F = fun () ->
- lists:foreach(fun (Msg) -> mnesia:delete_object(Msg) end, Messages)
- end,
- mnesia:transaction(F).
+%%--------------------------------------------------------------------
+%% @spec init(Args) -> {ok, State} |
+%% {ok, State, Timeout} |
+%% ignore |
+%% {stop, Reason}
+%% @doc Initiates the server
+%% @end
+%%--------------------------------------------------------------------
+init([]) ->
+ init_store(),
+ {ok, #state{}}.
+
+%%--------------------------------------------------------------------
+%% @spec
+%% handle_call(Request, From, State) -> {reply, Reply, State} |
+%% {reply, Reply, State, Timeout} |
+%% {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, Reply, State} |
+%% {stop, Reason, State}
+%% @doc Handling call messages
+%% @end
+%%--------------------------------------------------------------------
+handle_call({save_msg, Addressee, Body}, _From, State) ->
+ store_message(Addressee, Body),
+ {reply, ok, State};
+
+handle_call({find_msgs, Addressee}, _From, State) ->
+ Messages = get_messages(Addressee),
+ {reply, {ok, Messages}, State};
+handle_call (stop, _From, State) ->
+ io:format("Shutting down...~n"),
+ mnesia:stop(),
+ {stop, normal, State};
+
+handle_call(_Request, _From, State) ->
+ {reply, ignored_message, State}.
+
+%%--------------------------------------------------------------------
+%% @spec handle_cast(Msg, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State}
+%% @doc Handling cast messages
+%% @end
+%%--------------------------------------------------------------------
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% @spec handle_info(Info, State) -> {noreply, State} |
+%% {noreply, State, Timeout} |
+%% {stop, Reason, State}
+%% @doc Handling all non call/cast messages
+%% @end
+%%--------------------------------------------------------------------
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% @spec terminate(Reason, State) -> void()
+%% @doc This function is called by a gen_server when it is about to
+%% terminate. It should be the opposite of Module:init/1 and do any necessary
+%% cleaning up. When it returns, the gen_server terminates with Reason.
+%% The return value is ignored.
+%% @end
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+ ok.
+
+%%--------------------------------------------------------------------
+%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
+%% @doc Convert process state when code is changed
+%% @end
+%%--------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
+init_store () ->
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ try
+ mnesia:table_info(chat_message, type)
+ catch
+ exit: _ ->
+ mnesia:create_table(chat_message, [{attributes, record_info(fields, chat_message)},
+ {type, bag},
+ {disc_copies, [node()]}])
+ end.
+
get_messages (Addressee) ->
F = fun () ->
Query = qlc:q([M || M <- mnesia:table(chat_message), M#chat_message.addressee =:= Addressee]),
@@ -56,22 +156,16 @@ get_messages (Addressee) ->
end,
{atomic, Messages} = mnesia:transaction(F),
Messages.
-
+
store_message (Addressee, Body) ->
F = fun () ->
{_, CreatedOn, _} = erlang:now(),
mnesia:write(#chat_message{addressee = Addressee, body = Body, created_on = CreatedOn})
end,
mnesia:transaction(F).
-
-init_store () ->
- mnesia:create_schema([node()]),
- mnesia:start(),
- try
- mnesia:table_info(chat_message, type)
- catch
- exit: _ ->
- mnesia:create_table(chat_message, [{attributes, record_info(fields, chat_message)},
- {type, bag},
- {disc_copies, [node()]}])
- end.
+
+delete_messages (Messages) ->
+ F = fun () ->
+ lists:foreach(fun (Msg) -> mnesia:delete_object(Msg) end, Messages)
+ end,
+ mnesia:transaction(F).
View
@@ -0,0 +1,77 @@
+-module (message_store_old).
+-compile(export_all).
+-include_lib("stdlib/include/qlc.hrl").
+-define (SERVER, message_store).
+
+-record (chat_message, {addressee, body, created_on}).
+
+save_message (Addressee, Body) ->
+ global:send(?SERVER, {save_msg, Addressee, Body}).
+
+find_messages (Addressee) ->
+ global:send(?SERVER, {find_msgs, Addressee, self()}),
+ receive
+ {ok, Messages} ->
+ Messages
+ end.
+
+start () ->
+ server_util:start(?SERVER, {message_store, run, [true]}).
+
+stop () ->
+ server_util:stop(?SERVER).
+
+run (FirstTime) ->
+ if
+ FirstTime == true ->
+ init_store(),
+ run(false);
+ true ->
+ receive
+ {save_msg, Addressee, Body} ->
+ store_message(Addressee, Body),
+ run(FirstTime);
+ {find_msgs, Addressee, Pid} ->
+ Messages = get_messages(Addressee),
+ Pid ! {ok, Messages},
+ run(FirstTime);
+ shutdown ->
+ mnesia:stop(),
+ io:format("Shutting down...~n")
+ end
+ end.
+
+delete_messages (Messages) ->
+ F = fun () ->
+ lists:foreach(fun (Msg) -> mnesia:delete_object(Msg) end, Messages)
+ end,
+ mnesia:transaction(F).
+
+get_messages (Addressee) ->
+ F = fun () ->
+ Query = qlc:q([M || M <- mnesia:table(chat_message), M#chat_message.addressee =:= Addressee]),
+ Results = qlc:e(Query),
+ delete_messages(Results),
+ [Message#chat_message.body || Message <- Results]
+ end,
+ {atomic, Messages} = mnesia:transaction(F),
+ Messages.
+
+store_message (Addressee, Body) ->
+ F = fun () ->
+ {_, CreatedOn, _} = erlang:now(),
+ mnesia:write(#chat_message{addressee = Addressee, body = Body, created_on = CreatedOn})
+ end,
+ mnesia:transaction(F).
+
+init_store () ->
+ mnesia:create_schema([node()]),
+ mnesia:start(),
+ try
+ mnesia:table_info(chat_message, type)
+ catch
+ exit: _ ->
+ mnesia:create_table(chat_message, [{attributes, record_info(fields, chat_message)},
+ {type, bag},
+ {disc_copies, [node()]}])
+ end.
View
@@ -0,0 +1,47 @@
+-module (misc_server).
+-behaviour (gen_server).
+-export ([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
+-export ([start_link/0, add/2, subtract/2, add_and_subtract/2, stop/0]).
+
+% Client functions
+start_link () ->
+ gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+add (A, B) ->
+ gen_server:call(?MODULE, {add, A, B}).
+
+subtract (A, B) ->
+ gen_server:call(?MODULE, {subtract, A, B}).
+
+add_and_subtract(A, B) ->
+ [misc_server:add(A, B), misc_server:subtract(A, B)].
+
+stop () ->
+ gen_server:cast(?MODULE, stop).
+
+init ([]) ->
+ {ok, []}.
+
+handle_call ({subtract, A, B}, _From, State) ->
+ {reply, {ok, A - B}, State};
+handle_call ({add, A, B}, _From, State) ->
+ {reply, {ok, A + B}, State};
+handle_call (_Request, _From, State) ->
+ {reply, ignored, State}.
+
+handle_cast (stop, State) ->
+ {stop, normal, State};
+handle_cast (_Msg, State) ->
+ {noreply, State}.
+
+handle_info (_Info, State) ->
+ io:format("Info message received: ~p~n", [_Info]),
+ {noreply, State}.
+
+terminate (_Reason, _State) ->
+ io:format("Server is stopping...~n"),
+ ok.
+
+code_change (_OldVsn, State, _Extra) ->
+ {ok, State}.
+

0 comments on commit 2d86953

Please sign in to comment.