aboutsummaryrefslogtreecommitdiff
path: root/learn-you-some-erlang/kitty_server.erl
diff options
context:
space:
mode:
Diffstat (limited to 'learn-you-some-erlang/kitty_server.erl')
-rw-r--r--learn-you-some-erlang/kitty_server.erl74
1 files changed, 74 insertions, 0 deletions
diff --git a/learn-you-some-erlang/kitty_server.erl b/learn-you-some-erlang/kitty_server.erl
new file mode 100644
index 0000000..a40e20a
--- /dev/null
+++ b/learn-you-some-erlang/kitty_server.erl
@@ -0,0 +1,74 @@
+%%%%% Naive version
+-module(kitty_server).
+
+-export([start_link/0, order_cat/4, return_cat/2, close_shop/1]).
+
+-record(cat, {name, color=green, description}).
+
+%%% Client API
+start_link() -> spawn_link(fun init/0).
+
+%% Synchronous call
+order_cat(Pid, Name, Color, Description) ->
+ Ref = erlang:monitor(process, Pid),
+ Pid ! {self(), Ref, {order, Name, Color, Description}},
+ receive
+ {Ref, Cat = #cat{}} ->
+ erlang:demonitor(Ref, [flush]),
+ Cat;
+ {'DOWN', Ref, process, Pid, Reason} ->
+ erlang:error(Reason)
+ after 5000 ->
+ erlang:error(timeout)
+ end.
+
+%% This call is asynchronous
+return_cat(Pid, Cat = #cat{}) ->
+ Pid ! {return, Cat},
+ ok.
+
+%% Synchronous call
+close_shop(Pid) ->
+ Ref = erlang:monitor(process, Pid),
+ Pid ! {self(), Ref, terminate},
+ receive
+ {Ref, ok} ->
+ erlang:demonitor(Ref, [flush]),
+ ok;
+ {'DOWN', Ref, process, Pid, Reason} ->
+ erlang:error(Reason)
+ after 5000 ->
+ erlang:error(timeout)
+ end.
+
+%%% Server functions
+init() -> loop([]).
+
+loop(Cats) ->
+ receive
+ {Pid, Ref, {order, Name, Color, Description}} ->
+ if Cats =:= [] ->
+ Pid ! {Ref, make_cat(Name, Color, Description)},
+ loop(Cats);
+ Cats =/= [] -> % got to empty the stock
+ Pid ! {Ref, hd(Cats)},
+ loop(tl(Cats))
+ end;
+ {return, Cat = #cat{}} ->
+ loop([Cat|Cats]);
+ {Pid, Ref, terminate} ->
+ Pid ! {Ref, ok},
+ terminate(Cats);
+ Unknown ->
+ %% do some logging here too
+ io:format("Unknown message: ~p~n", [Unknown]),
+ loop(Cats)
+ end.
+
+%%% Private functions
+make_cat(Name, Col, Desc) ->
+ #cat{name=Name, color=Col, description=Desc}.
+
+terminate(Cats) ->
+ [io:format("~p was set free.~n",[C#cat.name]) || C <- Cats],
+ ok.