Skip to content

Commit

Permalink
Add the resource_discovery application from the book.
Browse files Browse the repository at this point in the history
  • Loading branch information
tmcgilchrist committed Jan 8, 2012
1 parent ca33ba0 commit fd17b16
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 0 deletions.
16 changes: 16 additions & 0 deletions apps/resource_discovery/src/rd_app.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-module(rd_app).

-behaviour(application).

-export([start/2, stop/1]).

start(_StartType, _StartArgs) ->
case rd_sup:start_link() of
{ok, Pid} ->
{ok, Pid};
Other ->
{error, Other}
end.

stop(_State) ->
ok.
116 changes: 116 additions & 0 deletions apps/resource_discovery/src/rd_server.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
-module(rd_server).

-behaviour(gen_server).

-export([
start_link/0,
add_target_resource_type/1,
add_local_resource/2,
fetch_resources/1,
trade_resources/0
]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).

-define(SERVER, ?MODULE).

-record(state, {target_resource_types,
local_resource_tuples,
found_resource_tuples}).

start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

init([]) ->
{ok, #state{target_resource_types = [],
local_resource_tuples = dict:new(),
found_resource_tuples = dict:new()}}.

add_target_resource_type(Type) ->
gen_server:cast(?SERVER, {add_target_resource_type, Type}).

add_local_resource(Type, Instance) ->
gen_server:cast(?SERVER, {add_local_resource, {Type, Instance}}).

handle_cast({add_target_resource_type, Type}, State) ->
TargetTypes = State#state.target_resource_types,
NewTargetTypes = [Type | lists:delete(Type, TargetTypes)],
{noreply, State#state{target_resource_types = NewTargetTypes}};
handle_cast({add_local_resource, {Type, Instance}}, State) ->
ResourceTuples = State#state.local_resource_tuples,
NewResourceTuples = add_resource(Type, Instance, ResourceTuples),
{noreply, State#state{local_resource_tuples = NewResourceTuples}};
handle_cast(trade_resources, State) ->
ResourceTuples = State#state.local_resource_tuples,
AllNodes = [node() | nodes()],
lists:foreach(
fun(Node) ->
gen_server:cast({?SERVER, Node},
{trace_resources, {node(), ResourceTuples}})
end,
AllNodes),
{noreply, State};
handle_cast({trade_resources, {ReplyTo, Remotes}},
#state{local_resource_tuples = Locals,
target_resource_types = TargetTypes,
found_resource_tuples = OldFound} = State) ->
FilteredRemotes = resources_for_types(TargetTypes, Remotes), % Checks for wanted resources
NewFound = add_resources(FilteredRemotes, OldFound), % Adds to know resources
case ReplyTo of
noreply ->
ok;
_ ->
gen_server:cast({?SERVER, ReplyTo},
{trace_resources, {noreply, Locals}})
end,
{noreply, State#state{found_resource_tuples = NewFound}}.





handle_call({fetch_resources, Type}, _From, State) ->
{reply, dict:find(Type, State#state.found_resource_tuples), State}.


fetch_resources(Type) ->
gen_server:call(?SERVER, {fetch_resources, Type}).

trade_resources() ->
gen_server:cast(?SERVER, trace_resources).

add_resources([{Type, Resource} | T], ResourceTuples) ->
add_resources(T, add_resource(Type, Resource, ResourceTuples));
add_resources([], ResourceTuples) ->
ResourceTuples.

add_resource(Type, Resource, ResourceTuples) ->
case dict:find(Type, ResourceTuples) of
{ok, ResourceList} ->
NewList = [Resource | lists:delete(Resource, ResourceList)],
dict:store(Type, NewList, ResourceTuples);
error ->
dict:store(Type, [Resource], ResourceTuples)
end.

resources_for_types(Types, ResourceTuples) ->
Fun =
fun(Type, Acc) ->
case dict:find(Type, ResourceTuples) of
{ok, List} ->
[{Type, Instance} || Instance <- List] ++ Acc;
error ->
Acc
end
end,
lists:foldl(Fun, [], Types).

handle_info(_, State) ->
{ok, State}.

terminate(_Reason, _State) ->
ok.

code_change(_OldVsn, State, _Extra) ->
{ok, State}.
21 changes: 21 additions & 0 deletions apps/resource_discovery/src/rd_sup.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-module(rd_sup).

-behaviour(supervisor).

%% API
-export([start_link/0]).

%% Supervisor callbacks
-export([init/1]).

-define(SERVER, ?MODULE).

start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).

init([]) ->
Discovery = {rd_server, {rd_server, start_link, []},
permanent, 2000, worker, [rd_server]},
Children = [Discovery],
RestartStrategy = {one_for_one, 4, 3600},
{ok, {RestartStrategy, Children}}.
17 changes: 17 additions & 0 deletions apps/resource_discovery/src/resource_discovery.app.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{application, resource_discovery,
[
{description, "Resource Discovery"},
{vsn, "0.1.0"},
{modules, [
rd_app,
rd_sup,
rd_server
]},
{registered, []},
{applications, [
kernel,
stdlib
]},
{mod, { rd_app, []}},
{env, []}
]}.

0 comments on commit fd17b16

Please sign in to comment.