With the digraph module I am able to write links between my hosts, my hosts are: karoten, ultraten, muloten, arsen, masculen, colen, pollen.
So I define them at the first time
(beta@karoten)425> f(D), D = digraph:new(). % a new digraph
{graph,22,23,24,true}
(beta@karoten)426> servers:add(D, [karoten,ultraten,muloten,arsen,masculen,colen,pollen]).
ok
Now I can manipulate my nodes (my servers)
(beta@karoten)427> servers:connect(D, karoten, [ultraten,{muloten,http}, arsen, {masculen,ssh}]).
ok
karoten can reach ultraten, and muloten with http, arsen, and masculen with ssh.
(beta@karoten)428> servers:connect(D, colen, [{muloten,http}, arsen, {pollen,ssh}]).
ok
colen can reach muloten with http, arsen, and pollen with ssh.
So let's find colen links:
(beta@karoten)429> servers:links(D, colen).
[{colen,muloten,http},{colen,arsen,[]},{colen,pollen,ssh}]
This exactly what I've written before, good ...
And muloten links:
(beta@karoten)430> servers:links(D, muloten).
[{karoten,muloten,http},{colen,muloten,http}]
This is deduced from what I've describe before...
Now let's imagine we want to find a way to reach one node from another:
(beta@karoten)431> digraph:get_path(D, karoten, arsen).
[karoten,arsen]
Karoten seems to be connected with arsen.
Let's create a new link, between ultraten and colen:
(beta@karoten)434> servers:connect(D, ultraten, colen).
['$e'|7]
Let's try to reach pollen from karoten:
(beta@karoten)435> digraph:get_path(D, karoten, pollen).
[karoten,ultraten,colen,pollen]
So the way is: thru ultraten, colen, karoten can reach pollen...
Now let's design a more web design approach, with a firewall, a load balancer lb, and various httpd and application servers, finally databases:
(beta@karoten)436> servers:add(D, [firewall,lb,http1,http2,http3,app1,app2,app3,app4,db1,db2]).
ok
The firewall is directly connected to the load balancer:
(beta@karoten)437> servers:connect(D, firewall, lb).
ok
The load balancer distribute the load to three httpd:
(beta@karoten)438> servers:connect(D, lb, [http1,http2,http3]).
ok
(beta@karoten)439> servers:connect(D, http1, [app1,app2,app3]).
ok
(beta@karoten)440> servers:connect(D, http2, [app2,app3]).
ok
(beta@karoten)441> servers:connect(D, http3, [app3]).
ok
(beta@karoten)442> servers:connect(D, app3,[db1,db2]).
ok
(beta@karoten)443> servers:connect(D, app2, [db1]).
ok
(beta@karoten)444> servers:connect(D, app1, db2).
['$e'|21]
Finally I can find a path between the firewall and the database 2:
(beta@karoten)445> digraph:get_path(D, firewall, db2).
[firewall,lb,http3,app3,db2]
Now the code:
module(servers).
-export([add/2,del/2,connect/3,links/2,reachable/2]).
add(Graph, Servers) when list(Servers) ->
lists:foreach(fun(X) -> digraph:add_vertex(Graph, X) end, Servers);
add(Graph, Server) ->
digraph:add_vertex(Graph, Server).
del(Graph, Servers) when list(Servers) ->
lists:foreach(fun(X) -> digraph:del_vertex(Graph, X) end, Servers);
del(Graph, Server) ->
digraph:del_vertex(Graph, Server).
connect(_Graph, _Server, []) ->
ok;
connect(Graph, Server, [ {S, L} | Servers ]) ->
digraph:add_edge(Graph, Server, S, L),
connect(Graph, Server, Servers);
connect(Graph, Server, [ S | Servers ]) ->
digraph:add_edge(Graph, Server, S),
connect(Graph, Server, Servers);
% connect(Graph, Server, Servers) when list(Servers) ->
% lists:foreach(fun(X) -> digraph:add_edge(Graph, Server, X) end, Servers);
connect(Graph, Server, S) ->
digraph:add_edge(Graph, Server, S).
links(Graph, Server) ->
lists:map(fun(X) -> {_, S1, S2, Label} = digraph:edge(Graph, X), {S1, S2, Label} end, digraph:edges(Graph, Server)).
reachable(Graph, Server) when list(Server) ->
digraph_utils:reachable(Server, Graph);
reachable(Graph, Server) ->
digraph_utils:reachable([Server], Graph).
No comments:
Post a Comment