diff options
author | Nathan Lasseter <nathan.je.lasseter@googlemail.com> | 2011-12-23 10:11:48 +0000 |
---|---|---|
committer | Nathan Lasseter <nathan.je.lasseter@googlemail.com> | 2011-12-23 10:11:48 +0000 |
commit | b5c22a8a96203ad6b656524fe5ecf246a89efb58 (patch) | |
tree | bf098b067149c41fa3a8f46063909927b904fe46 /erlbal_n.erl | |
parent | 2db1bbcde1e0e643a85619a1be350225264d3c10 (diff) |
Started work on erlbal_n. Changed names to reflect.erlbal-n
Diffstat (limited to 'erlbal_n.erl')
-rw-r--r-- | erlbal_n.erl | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/erlbal_n.erl b/erlbal_n.erl new file mode 100644 index 0000000..fba8621 --- /dev/null +++ b/erlbal_n.erl @@ -0,0 +1,91 @@ +-module(erlbal_n). +-export([make_request/2, start_bal/0, stop_bal/1, start_server/5, stop_server/2, list_servers/1]). + +start_server(Balancer, Node, Fun, LoadFun, INITSTATE) when is_function(Fun, 2) andalso is_function(LoadFun, 0) andalso is_list(INITSTATE) -> + PID = spawn(Node, fun() -> server_loop(Fun, LoadFun, INITSTATE) end), + Balancer ! {add_node, PID}. + +stop_server(Balancer, PID) -> + Balancer ! {del_node, PID}, + PID ! die. + +list_servers(Balancer) -> + Balancer ! {list_nodes, self()}, + receive Nodes -> Nodes end. + +server_loop(Fun, LoadFun, STATE) -> + receive + {request, From, Serverlist, ARGS} -> + {Ret, NEWSTATE} = Fun(ARGS, STATE), + From ! Ret, + updatestates(Serverlist, self(), NEWSTATE), + server_loop(Fun, LoadFun, NEWSTATE); + {load, From} -> + From ! LoadFun(), + server_loop(Fun, LoadFun, STATE); + {update, NEWSTATE} -> + server_loop(Fun, LoadFun, NEWSTATE); + die -> + ok + end. + +updatestates([], _, _) -> + ok; +updatestates([H|T], H, NEWSTATE) -> + updatestates(T, H, NEWSTATE); +updatestates([H|T], P, NEWSTATE) -> + H ! {update, NEWSTATE}, + updatestates(T, P, NEWSTATE). + +start_bal() -> + spawn(fun() -> bal_loop([]) end). + +stop_bal(Balancer) -> + Balancer ! die. + +bal_loop(Serverlist) -> + receive + {add_node, PID} -> + bal_loop(Serverlist ++ [PID]); + {del_node, PID} -> + bal_loop(Serverlist -- [PID]); + {list_nodes, From} -> + From ! Serverlist, + bal_loop(Serverlist); + {request, From, ARGS} -> + if + length(Serverlist) > 0 -> + PID = bal_worker(Serverlist), + PID ! {request, From, Serverlist, ARGS}, + bal_loop(Serverlist); + true -> + bal_loop(Serverlist) + end; + die -> + ok + end. + +bal_worker([H|T]) -> + H ! {load, self()}, + receive + N -> + bal_worker(T, N, H) + end. +bal_worker([], _, PID) -> + PID; +bal_worker([H|T], Best, PID) -> + H ! {load, self()}, + receive + N -> + if + N > Best -> + bal_worker(T, N, H); + true -> + bal_worker(T, Best, PID) + end + end. + + +make_request(Balancer, ARGS) when is_list(ARGS)-> + Balancer ! {request, self(), ARGS}, + receive Ret -> Ret end. |