Created
January 29, 2012 07:43
-
-
Save garrensmith/1697736 to your computer and use it in GitHub Desktop.
Fridge Process implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -module(kitchen2). | |
| -compile(export_all). | |
| start(Items) -> | |
| spawn_link(?MODULE, restarter, [Items]), | |
| timer:sleep(100). %delay for processes to startup befor can issue commands | |
| % register(fridge, Pid). | |
| restarter(Items) -> | |
| process_flag(trap_exit, true), | |
| Pid = spawn_link(?MODULE, fridge, [Items]), | |
| register(fridge, Pid), | |
| cool_spawner(), | |
| receive | |
| {'EXIT', Pid, normal} -> % not a crash | |
| ok; | |
| {'EXIT', Pid, shutdown} -> % manual termination, not a crash | |
| ok; | |
| {'EXIT', Pid, _} -> | |
| restarter([]) | |
| end. | |
| command(Msg) -> | |
| Ref = make_ref(), | |
| fridge ! {self(), Ref,Msg}, | |
| receive | |
| {_, Ref, Resp} -> Resp | |
| after 20 -> | |
| timeout | |
| end. | |
| store(Item) -> | |
| command({store, Item}). | |
| take(Item) -> | |
| command({take, Item}). | |
| list_items() -> | |
| command(list). | |
| turn_off() -> | |
| command(kill). | |
| take_from_fridge(Item, Foodlist) -> | |
| case lists:keymember(Item,1, Foodlist) of | |
| true -> | |
| ItemWithTemp = lists:keyfind(Item,1, Foodlist), | |
| {{ok, ItemWithTemp }, lists:keydelete(Item,1, Foodlist)}; | |
| false -> | |
| {{fail, "Item does not exist"}, Foodlist} | |
| end. | |
| fridge(Foodlist1) -> | |
| Foodlist = lists:sort(Foodlist1), % sort every time to make merging easy | |
| receive | |
| {_, _, unplug} -> | |
| start_temp_monitor(), | |
| fridge(Foodlist); | |
| {_,_, plug} -> | |
| stop_temp_monitor(), | |
| fridge(Foodlist); | |
| {From, Ref, kill} -> | |
| cooler ! {self(), make_ref(), kill}, | |
| From ! {self(), Ref, ok}; | |
| {From, Ref, list} -> | |
| From ! {self(), Ref, Foodlist}, | |
| fridge(Foodlist); | |
| {From, Ref, {store, Item}} -> | |
| From ! {self(), Ref, ok}, | |
| fridge([Item | Foodlist]); | |
| {From, Ref, {take, Item}} -> | |
| {Resp, NewFoodList} = take_from_fridge(Item, Foodlist), | |
| From ! {self(), Ref, Resp}, | |
| fridge(NewFoodList); | |
| {_, _, {cold, ColdFoodList}} -> | |
| NewFoodList = lists:ukeymerge(1,ColdFoodList, Foodlist), | |
| fridge(NewFoodList) | |
| end. | |
| temp_monitor(Temp) -> | |
| receive | |
| {_, _, kill} -> ok | |
| after 1000 -> | |
| if Temp > 15 -> | |
| io:format("WARNING: Temperature above 15 degrees~n"), | |
| temp_monitor(Temp + 1); | |
| true -> temp_monitor(Temp + 1) | |
| end | |
| end. | |
| start_temp_monitor() -> | |
| Pid = spawn_link(?MODULE, temp_monitor, [17]), | |
| register(temp_monitor, Pid), | |
| ok. | |
| stop_temp_monitor() -> | |
| temp_monitor ! {self(), make_ref(), kill}. | |
| cool_item(FoodItem) -> | |
| case FoodItem of | |
| {Item, Temp} when Temp > 10 -> {Item, Temp - 1}; | |
| {Item, Temp} when Temp =< 10 -> {Item, Temp} | |
| end. | |
| cool_spawner() -> | |
| Pid = spawn_link(?MODULE, cooler, []), | |
| register(cooler, Pid). | |
| cooler() -> | |
| receive | |
| {_, _, kill} -> ok | |
| after 300 -> | |
| Foodlist = command(list), | |
| ColdFoodList = lists:map(fun cool_item/1, Foodlist), | |
| command({cold, ColdFoodList}), | |
| cooler() | |
| end. | |
| test() -> | |
| test_take_from_fridge(), | |
| test_cool(), | |
| test_fridge(), | |
| test_unplug(), | |
| ok. | |
| test_unplug() -> | |
| start([{cheese,12}, {bread,8}]), | |
| command(unplug), | |
| timer:sleep(5000), | |
| command(plug), | |
| turn_off(). | |
| test_fridge() -> | |
| start([{cheese,12}, {bread,8}]), | |
| [{bread,8}, {cheese,12} ] = list_items(), | |
| ok = store({milk, 15}), | |
| [{bread,8}, {cheese,12}, {milk,15}] = list_items(), | |
| ok = store({crab,5}), | |
| {ok, {milk, 15}} = take(milk), | |
| [{bread,8}, {cheese,12}, {crab,5}] = list_items(), | |
| {fail, "Item does not exist"} = take(ham), | |
| ok = turn_off(), | |
| ok. | |
| test_cool() -> | |
| start([{cheese,9},{milk, 8},{bread,12}]), | |
| timer:sleep(400), | |
| [{bread,11},{cheese,9},{milk,8}] = list_items(), | |
| store({honey, 15}), | |
| timer:sleep(300), | |
| [{bread,10},{cheese,9},{honey,14},{milk,8}] = list_items(), | |
| ok = turn_off(), | |
| timer:sleep(200), | |
| ok. | |
| test_take_from_fridge() -> | |
| {{ok,{cheese,12}},[{bread,8},{crab,5}]} = take_from_fridge(cheese, [{bread,8}, {cheese,12}, {crab,5}]), | |
| {{fail,"Item does not exist"}, [{bread,8},{cheese,12},{crab,5}]} = take_from_fridge(mango, [{bread,8}, {cheese,12}, {crab,5}]), | |
| ok. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment