update for use with erlectricity 0.2 and fix status code
[fuzed.git] / elibs / rails_connection_pool.erl
blobc1e14314deab3bdd3d8b07a0b0781699f75e719f
1 -module(rails_connection_pool).
2 -compile(export_all).
5 %% Convenience Function
6 simple_handle_request(Arg,ServerInfo) ->
7 {Source, Resource} = rails_connection_pool:get(),
8 Response = rails_forwarder:handle_request(Resource, Arg, ServerInfo, 10000),
9 rails_connection_pool:refund({Source,Resource}),
10 Response.
13 handle_request(Arg,ServerInfo) ->
14 handle_request_helper(Arg,ServerInfo,0).
16 handle_request_helper(_Arg,_ServerInfo,Retries) when Retries > 1 ->
17 throw(timed_out);
18 handle_request_helper(Arg,ServerInfo,Retries) ->
19 Remote = fun(A,S,Target) ->
20 {Source, Handler} = rails_connection_pool:get(),
21 Response = rails_forwarder:rails_handle_request(Handler, A, S, 10000),
22 Target ! {rails_response, Response},
23 rails_connection_pool:refund({Source, Handler}) end,
24 _RequestProc = spawn(Remote(Arg,ServerInfo,self())),
25 receive
26 {rails_response, Response} ->
27 Response
28 after 5000 ->
29 handle_request_helper(Arg,ServerInfo, Retries+1)
30 end.
33 %% Server manipulation
34 start() ->
35 global:register_name(?MODULE, spawn(
36 fun() ->
37 process_flag(trap_exit, true),
38 rails_connection_pool:loop([],[]) end
42 add({Node, Proc}) when is_pid(Proc) ->
43 global:send(?MODULE, {add, {Node, Proc}}),
44 ok.
46 remove(Rsrc) ->
47 global:send(?MODULE, {remove, Rsrc}),
48 ok.
50 get() ->
51 global:send(?MODULE, {get, self()}),
52 receive
53 {node, X} ->
55 end.
57 refund(Node) ->
58 global:send(?MODULE, {refund, Node}),
59 ok.
61 list() ->
62 global:send(?MODULE, {list, self()}),
63 receive
64 {nodes, A} ->
66 end.
68 list_all() ->
69 global:send(?MODULE, {list_all, self()}),
70 receive
71 {all_nodes, A} ->
73 end.
75 remove_server(Server) ->
76 global:send(?MODULE, {remove_server, Server}),
77 ok.
79 remove_all() ->
80 global:send(?MODULE, {remove_all}),
81 ok.
83 remove_server_filter(Server, {Server, _X}) -> false;
84 remove_server_filter(_Server, {_NotServer, _X}) -> true.
86 loop([],A) ->
87 receive
88 {add, {Node, Proc}} when is_pid(Proc) ->
89 erlang:link(Proc),
90 loop([{Node,Proc}],[{Node,Proc}|A]);
91 {list, Pid} ->
92 Pid ! {nodes, []},
93 loop([],A);
94 {list_all, Pid} ->
95 Pid ! {all_nodes, A},
96 loop([],A);
97 {refund,Node} ->
98 Membership = lists:member(Node,A),
99 if
100 Membership ->
101 loop([Node],A);
102 true ->
103 loop([],A)
104 end;
105 {'EXIT', Pid, _Reason} ->
106 FilterFun = fun({_Node,MPid}) -> MPid /= Pid end,
107 loop([],lists:filter(FilterFun, A))
108 end;
109 loop(X,A) ->
110 receive
111 {add, {Node, Proc}} when is_pid(Proc)->
112 erlang:link(Proc),
113 I = {Node, Proc},
114 loop([I|X], [I|A]);
115 {remove, I} ->
116 loop(lists:delete(I,X), lists:delete(I,A));
117 {remove_server, Server} ->
118 PurgedX = lists:filter(fun(Z) -> remove_server_filter(Server, Z) end, X),
119 PurgedA = lists:filter(fun(Z) -> remove_server_filter(Server, Z) end, A),
120 loop(PurgedX, PurgedA);
121 {remove_all} ->
122 loop([],[]);
123 {list, Pid} ->
124 Pid ! {nodes, X},
125 loop(X,A);
126 {list_all, Pid} ->
127 Pid ! {all_nodes, A},
128 loop(X,A);
129 {get, Pid} ->
130 [Node|Rest] = X,
131 Pid ! {node, Node},
132 loop(Rest,A);
133 {refund,Node} ->
134 Membership = lists:member(Node,A),
136 Membership ->
137 loop(X ++ [Node],A);
138 true ->
139 loop(X,A)
140 end;
141 {'EXIT', Pid, _Reason} ->
142 FilterFun = fun({_Node,MPid}) -> MPid /= Pid end,
143 loop(lists:filter(FilterFun,X),lists:filter(FilterFun, A));
144 Other ->
145 io:format("~p loop(X,A) Received unknown message: ~p~n", [?MODULE, Other]),
146 loop(X,A)
147 end.