Просмотр исходного кода

Rename take_pid => take_member and fix race in test code

Seth Falcon 14 лет назад
Родитель
Сommit
456f409595
3 измененных файлов с 40 добавлено и 41 удалено
  1. 3 3
      README.org
  2. 16 16
      src/pooler.erl
  3. 21 22
      test/pooler_test.erl

+ 3 - 3
README.org

@@ -107,7 +107,7 @@ Here's an example session:
 application:start(pooler).
 P = pooler:take_member(),
 % use P
-pooler:return_pid(P, ok).
+pooler:return_member(P, ok).
 #+END_SRC
 
 Once started, the main interaction you will have with pooler is through
@@ -186,9 +186,9 @@ Pool removal has two forms:
   pool is removed.
 
 #+BEGIN_SRC erlang
-  -spec(take_pid() -> pid()).
+  -spec(take_member() -> pid()).
   
-  -spec(return_pid(pid(), ok | fail) -> ignore).
+  -spec(return_member(pid(), ok | fail) -> ignore).
   
   -spec(status() -> [term()]).
   

+ 16 - 16
src/pooler.erl

@@ -31,8 +31,8 @@
 -export([start/1,
          start_link/1,
          stop/0,
-         take_pid/0,
-         return_pid/2,
+         take_member/0,
+         return_member/2,
          remove_pool/2,
          add_pool/1,
          pool_stats/1,
@@ -62,12 +62,12 @@ start(Config) ->
 stop() ->
     gen_server:call(?SERVER, stop).
 
-take_pid() ->
-    gen_server:call(?SERVER, take_pid).
+take_member() ->
+    gen_server:call(?SERVER, take_member).
 
-return_pid(Pid, Status) when Status == ok; Status == fail ->
+return_member(Pid, Status) when Status == ok; Status == fail ->
     CPid = self(),
-    gen_server:cast(?SERVER, {return_pid, Pid, Status, CPid}),
+    gen_server:cast(?SERVER, {return_member, Pid, Status, CPid}),
     ok.
 
 remove_pool(Name, How) when How == graceful; How == immediate ->
@@ -106,10 +106,10 @@ init(Config) ->
     process_flag(trap_exit, true),
     {ok, State}.
 
-handle_call(take_pid, {CPid, _Tag}, State) ->
+handle_call(take_member, {CPid, _Tag}, State) ->
     % FIXME: load-balance?
     PoolName = hd(dict:fetch_keys(State#state.pools)),
-    {NewPid, NewState} = take_pid(PoolName, CPid, State),
+    {NewPid, NewState} = take_member(PoolName, CPid, State),
     {reply, NewPid, NewState};
 handle_call(stop, _From, State) ->
     % FIXME:
@@ -125,15 +125,15 @@ handle_call(_Request, _From, State) ->
     {noreply, ok, State}.
 
 
-handle_cast({return_pid, Pid, Status, CPid}, State) ->
-    {noreply, do_return_pid({Pid, Status}, CPid, State)};
+handle_cast({return_member, Pid, Status, CPid}, State) ->
+    {noreply, do_return_member({Pid, Status}, CPid, State)};
 handle_cast(_Msg, State) ->
     {noreply, State}.
 
 handle_info({'EXIT', Pid, Reason}, State) ->
     % error_logger:info_report({got_exit, Pid, Reason}),
     State1 = case dict:find(Pid, State#state.in_use_pids) of
-                 {ok, {_PName, CPid}} -> do_return_pid({Pid, fail}, CPid, State);
+                 {ok, {_PName, CPid}} -> do_return_member({Pid, fail}, CPid, State);
                  error ->
                      CPMap = State#state.consumer_to_pid,
                      case dict:find(Pid, CPMap) of
@@ -144,7 +144,7 @@ handle_info({'EXIT', Pid, Reason}, State) ->
                                         _Crash -> fail
                                     end,
                              lists:foldl(fun(P, S) ->
-                                                 do_return_pid({P, IsOk}, Pid, S)
+                                                 do_return_member({P, IsOk}, Pid, S)
                                          end, State, Pids);
                          error ->
                              State
@@ -194,7 +194,7 @@ add_pids(PoolName, N, State) ->
             {max_count_reached, State}
     end.
 
-take_pid(PoolName, From, State) ->
+take_member(PoolName, From, State) ->
     #state{pools = Pools, in_use_pids = InUse, consumer_to_pid = CPMap} = State,
     Pool = dict:fetch(PoolName, Pools),
     #pool{max_count = Max, free_pids = Free, in_use_count = NumInUse} = Pool,
@@ -204,7 +204,7 @@ take_pid(PoolName, From, State) ->
         [] when NumInUse < Max ->
             case add_pids(PoolName, 1, State) of
                 {ok, State1} ->
-                    take_pid(PoolName, From, State1);
+                    take_member(PoolName, From, State1);
                 {max_count_reached, _} ->
                     {error_no_pids, State}
             end;
@@ -217,7 +217,7 @@ take_pid(PoolName, From, State) ->
                               consumer_to_pid = CPMap1}}
     end.
 
-do_return_pid({Pid, Status}, CPid, State) ->
+do_return_member({Pid, Status}, CPid, State) ->
     #state{in_use_pids = InUse, pools = Pools,
            consumer_to_pid = CPMap} = State,
     case dict:find(Pid, InUse) of
@@ -232,7 +232,7 @@ do_return_pid({Pid, Status}, CPid, State) ->
                          pools = dict:store(PoolName, Pool1, Pools),
                          consumer_to_pid = cpmap_remove(Pid, CPid, CPMap)};
         error ->
-            error_logger:warning_report({return_pid_not_found, Pid, dict:to_list(InUse)}),
+            error_logger:warning_report({return_member_not_found, Pid, dict:to_list(InUse)}),
             State
     end.
 

+ 21 - 22
test/pooler_test.erl

@@ -9,10 +9,7 @@
 % and take a new pid, stop cleanly, and crash.
 
 start_user() ->
-    spawn(fun() ->
-                  TC = pooler:take_pid(),
-                  user_loop(TC)
-          end).
+    spawn(fun() -> user_loop(start) end).
 
 user_id(Pid) ->
     Pid ! {get_tc_id, self()},
@@ -30,6 +27,8 @@ user_stop(Pid) ->
 user_crash(Pid) ->
     Pid ! crash.
 
+user_loop(Atom) when Atom =:= error_no_pids orelse Atom =:= start ->
+    user_loop(pooler:take_member());
 user_loop(MyTC) ->
     receive
         {get_tc_id, From} ->
@@ -42,11 +41,11 @@ user_loop(MyTC) ->
             From ! pooled_gs:ping_count(MyTC),
             user_loop(MyTC);
         new_tc ->
-            pooler:return_pid(MyTC, ok),
-            MyNewTC = pooler:take_pid(),
+            pooler:return_member(MyTC, ok),
+            MyNewTC = pooler:take_member(),
             user_loop(MyNewTC);
         stop ->
-            pooler:return_pid(MyTC, ok),
+            pooler:return_member(MyTC, ok),
             stopped;
         crash ->
             erlang:error({user_loop, kaboom})
@@ -120,16 +119,16 @@ pooler_basics_test_() ->
      [
       {"take and return one",
        fun() ->
-               P = pooler:take_pid(),
+               P = pooler:take_member(),
                ?assertMatch({"type-0", _Id}, pooled_gs:get_id(P)),
-               ok = pooler:return_pid(P, ok)
+               ok = pooler:return_member(P, ok)
        end},
 
       {"pids are created on demand until max",
        fun() ->
-               Pids = [pooler:take_pid(), pooler:take_pid(), pooler:take_pid()],
-               ?assertMatch(error_no_pids, pooler:take_pid()),
-               ?assertMatch(error_no_pids, pooler:take_pid()),
+               Pids = [pooler:take_member(), pooler:take_member(), pooler:take_member()],
+               ?assertMatch(error_no_pids, pooler:take_member()),
+               ?assertMatch(error_no_pids, pooler:take_member()),
                PRefs = [ R || {_T, R} <- [ pooled_gs:get_id(P) || P <- Pids ] ],
                % no duplicates
                ?assertEqual(length(PRefs), length(lists:usort(PRefs)))
@@ -138,19 +137,19 @@ pooler_basics_test_() ->
 
       {"pids are reused most recent return first",
        fun() ->
-               P1 = pooler:take_pid(),
-               P2 = pooler:take_pid(),
+               P1 = pooler:take_member(),
+               P2 = pooler:take_member(),
                ?assertNot(P1 == P2),
-               ok = pooler:return_pid(P1, ok),
-               ok = pooler:return_pid(P2, ok),
+               ok = pooler:return_member(P1, ok),
+               ok = pooler:return_member(P2, ok),
                % pids are reused most recent first
-               ?assertEqual(P2, pooler:take_pid()),
-               ?assertEqual(P1, pooler:take_pid())
+               ?assertEqual(P2, pooler:take_member()),
+               ?assertEqual(P1, pooler:take_member())
        end},
 
       {"if a pid crashes it is replaced",
        fun() ->
-               Pids0 = [pooler:take_pid(), pooler:take_pid(), pooler:take_pid()],
+               Pids0 = [pooler:take_member(), pooler:take_member(), pooler:take_member()],
                Ids0 = [ pooled_gs:get_id(P) || P <- Pids0 ],
                % crash them all
                [ pooled_gs:crash(P) || P <- Pids0 ],
@@ -162,10 +161,10 @@ pooler_basics_test_() ->
 
       {"if a pid is returned with bad status it is replaced",
        fun() ->
-               Pids0 = [pooler:take_pid(), pooler:take_pid(), pooler:take_pid()],
+               Pids0 = [pooler:take_member(), pooler:take_member(), pooler:take_member()],
                Ids0 = [ pooled_gs:get_id(P) || P <- Pids0 ],
                % return them all marking as bad
-               [ pooler:return_pid(P, fail) || P <- Pids0 ],
+               [ pooler:return_member(P, fail) || P <- Pids0 ],
                Pids1 = get_n_pids(3, []),
                Ids1 = [ pooled_gs:get_id(P) || P <- Pids1 ],
                [ ?assertNot(lists:member(I, Ids0)) || I <- Ids1 ]
@@ -248,7 +247,7 @@ pooler_integration_test_() ->
 get_n_pids(0, Acc) ->
     Acc;
 get_n_pids(N, Acc) ->
-    case pooler:take_pid() of
+    case pooler:take_member() of
         error_no_pids ->
             get_n_pids(N, Acc);
         Pid ->