aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/client.erl85
-rw-r--r--common/server.erl64
-rw-r--r--server/client.erl25
-rw-r--r--server/dispatcher.erl18
4 files changed, 109 insertions, 83 deletions
diff --git a/client/client.erl b/client/client.erl
index f8d5de2..d0bae4c 100644
--- a/client/client.erl
+++ b/client/client.erl
@@ -1,5 +1,19 @@
-module(client).
--export([register/3, login/3, list/0, handle/3]).
+-export([register/3, login/3, list/0, handle/2]).
+
+contains([], _) ->
+ false;
+contains([H|_], H) ->
+ true;
+contains([_|T], Search) ->
+ contains(T, Search).
+
+checkLogin(Value) ->
+ checkLogin(Value, contains(registered(), cli)).
+checkLogin(Value, Value) ->
+ true;
+checkLogin(_, _) ->
+ throw({error, login_state}).
buildNode(Server) ->
list_to_atom("distributed_music_system_main_node@" ++ Server).
@@ -13,24 +27,21 @@ register(Server, Name, Password) ->
{_, ok, Msg} ->
Msg;
{_, error, Msg} ->
- Msg
+ {error, Msg}
end.
login(Server, Name, Password) ->
+ code:purge(server),
+ code:load_abs("../common/server"),
+
try checkLogin(false) of
_ ->
- rpc(Server, login, [self(), {Name, Password}]),
+ rpc(Server, login, [self(), {node(), Name, Password}]),
receive
- {_, ok, {ok, {logged_in, Client}}} ->
- code:purge(server),
- code:load_abs("../common/server"),
- case server:start(cli, client, Client) of
- true ->
- {ok, logged_in};
- _ ->
- {error, unable_to_login}
- end;
- {_, error, Msg} ->
+ {_, ok, {ok, {logged_in, {Pid, _}}}} ->
+ server:registration(Pid, cli),
+ {ok, logged_in};
+ {_, _, Msg} ->
Msg;
Msg ->
Msg
@@ -40,52 +51,26 @@ login(Server, Name, Password) ->
{error, logged_in}
end.
-contains([], _) ->
- false;
-contains([H|_], H) ->
- true;
-contains([_|T], Search) ->
- contains(T, Search).
-
-checkLogin(Value) ->
- checkLogin(Value, contains(registered(), cli)).
-checkLogin(Value, Value) ->
- true;
-checkLogin(_, _) ->
- throw({error, login_state}).
-
list() ->
try checkLogin(true) of
_ ->
- cli ! {self(), list},
- receive
- {_, ok, Msg} ->
- Msg;
- {_, error, Msg} ->
- {error, Msg};
- Msg ->
- {error, Msg}
- end
+ server:rpc(cli, list)
catch
{error, login_state} ->
{error, not_logged_in}
end.
-handle(Cli, list, Client) ->
- Client ! {list},
+handle(list, Server) ->
+ Server ! list,
receive
- {_, {ok, List}} ->
- io:format("List: ~w~n", List),
- {{ok}, Client}
+ {ok, Msg} ->
+ {Msg, Server};
+ Msg ->
+ {Msg, Server}
end;
-handle(Cli, {test, X}, Client) ->
- Client ! {X},
- receive
- Msg ->
- io:format("Test: ~w~n~n", [Msg]),
- {{ok}, Client}
- end;
+handle({change_state, NewState}, _) ->
+ {{ok}, NewState};
-handle(_, Cmd, Client) ->
- {{error, {unknown_command, Cmd}}, Client}.
+handle(Cmd, Server) ->
+ {{error, {unknown_command, Cmd}}, Server}.
diff --git a/common/server.erl b/common/server.erl
index 06922cc..bb64997 100644
--- a/common/server.erl
+++ b/common/server.erl
@@ -5,7 +5,7 @@
%% Visit http://www.pragmaticprogrammer.com/titles/jaerlang for more book information.
-module(server).
--export([start/2, start/3, rpc/2, swap_code/2]).
+-export([start/2, start/3, start_on_node/3, rpc/2, send/2, registration/2]).
start(Name, Mod) ->
register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)).
@@ -13,34 +13,58 @@ start(Name, Mod) ->
start(Name, Mod, State) ->
register(Name, spawn(fun() -> loop(Name, Mod, State) end)).
-swap_code(Name, Mod) -> rpc(Name, {swap_code, Mod}).
+start_on_node(Node, Mod, State) ->
+ Ref = make_ref(),
+ Pid = spawn(Node, fun() -> loop(Ref, Mod, State) end),
+ {Pid, Ref}.
-rpc(Name, Request) ->
- Name ! {self(), Request},
+send({Client, _}, Data) ->
+ send(Client, Data);
+send(Client, Data) ->
+ Client ! Data.
+
+wait_response({_, Name}) ->
+ wait_response(Name);
+wait_response(Name) ->
receive
{Name, crash} -> exit(rpc);
{Name, ok, Response} -> Response
end.
+rpc(Client, Request) ->
+ send(Client, {self(), Request}),
+ wait_response(Client).
+
+registration(Client, NewName) ->
+ send(Client, {register, NewName}).
+
loop(Name, Mod, OldState) ->
receive
- {From, {swap_code, NewCallbackMod}} ->
- From ! {Name, ok, ack},
- loop(Name, NewCallbackMod, OldState);
+ {register, NewName} ->
+ register(NewName, self()),
+ loop(NewName, Mod, OldState);
+
{From, Request} ->
- {Response, NewState} = Mod:handle(From, Request, OldState),
- From ! {Name, ok, Response},
- loop(Name, Mod, NewState)
- %% try Mod:handle(From, Request, OldState) of
- %% {Response, NewState} ->
- %% From ! {Name, ok, Response},
- %% loop(Name, Mod, NewState)
- %% catch
- %% _: Why ->
- %% log_the_error(Name, Request, Why),
- %% From ! {Name, crash},
- %% loop(Name, Mod, OldState)
- %% end
+ try Mod:handle(Request, OldState) of
+ {Response, NewState} ->
+ From ! {Name, ok, Response},
+ loop(Name, Mod, NewState)
+ catch
+ _: Why ->
+ log_the_error(Name, Request, Why),
+ From ! {Name, crash},
+ loop(Name, Mod, OldState)
+ end;
+
+ {'EXIT', From, Why} ->
+ try Mod:handle({'EXIT', From, Why}, OldState) of
+ NewState ->
+ loop(Name, Mod, NewState)
+ catch
+ _: Why ->
+ log_the_error(From, 'EXIT', Why),
+ loop(Name, Mod, OldState)
+ end
end.
log_the_error(Name, Request, Why) ->
diff --git a/server/client.erl b/server/client.erl
index 9d778f0..31d382f 100644
--- a/server/client.erl
+++ b/server/client.erl
@@ -1,23 +1,32 @@
-module(client).
-export([start/1, loop/1, register/2, login/2]).
-start(Client) ->
+start(Node) ->
process_flag(trap_exit, true),
- spawn(client, loop, [Client]).
+ {Client, Ref} = server:start_on_node(Node, client, undef),
+ link(Client),
+ Server = spawn_link(client, loop, [{Client, Ref}]),
+
+ case server:rpc({Client, Ref}, {change_state, Server}) of
+ {ok} ->
+ {ok, {Client, Ref}};
+ _ ->
+ {error, unknown_error}
+ end.
loop(Client) ->
receive
- {list} ->
- Client ! {ok, foo},
+ list ->
+ server:send(Client, {ok, {foo}}),
loop(Client);
- true ->
- Client ! {error, unknown_command},
+ Cmd ->
+ server:send(Client, {error, {unknown_command, Cmd}}),
loop(Client)
end.
register(Client, {Name, Password}) ->
dis ! {Client, {register, {Name, Password}}}.
-login(Client, {Name, Password}) ->
- dis ! {Client, {login, {Name, Password}}}.
+login(Client, {Node, Name, Password}) ->
+ dis ! {Client, {login, {Node, Name, Password}}}.
diff --git a/server/dispatcher.erl b/server/dispatcher.erl
index 390f9e5..4f1f58b 100644
--- a/server/dispatcher.erl
+++ b/server/dispatcher.erl
@@ -1,5 +1,5 @@
-module(dispatcher).
--export([start/0, init/0, handle/3]).
+-export([start/0, init/0, handle/2]).
start() ->
code:purge(server),
@@ -17,7 +17,7 @@ start() ->
init() ->
dict:new().
-handle(_, {register, {User, Password}}, Dict) ->
+handle({register, {User, Password}}, Dict) ->
case dict:find(User, Dict) of
{ok, _}->
{{error, duplicated_user}, Dict};
@@ -26,13 +26,21 @@ handle(_, {register, {User, Password}}, Dict) ->
{{ok, user_created}, dict:store(User, Password, Dict)}
end;
-handle(From, {login, {User, Password}}, Dict) ->
+handle({login, {Node, User, Password}}, Dict) ->
case dict:find(User, Dict) of
{ok, Password} ->
- {{ok, {logged_in, client:start(From)}}, Dict};
+ case client:start(Node) of
+ {ok, Pid} ->
+ {{ok, {logged_in, Pid}}, Dict};
+ _ ->
+ {{error, unable_to_login}, Dict}
+ end;
_ ->
{{error, user_or_password_invalid}, Dict}
end;
-handle(_, _, Dict) ->
+handle({'EXIT', _, _}, Dict) ->
+ Dict;
+
+handle(_, Dict) ->
{{error, unknown_command}, Dict}.