From b2a7dffcccd0f16453c82373892d2c4a4040b25e Mon Sep 17 00:00:00 2001 From: Feng Date: Sat, 2 Jan 2016 12:55:50 +0800 Subject: [PATCH] unit test --- src/ecpool.app.src | 2 +- src/ecpool.erl | 33 +++++++++++++++++++++++---------- src/ecpool_pool.erl | 6 ++---- src/ecpool_sup.erl | 10 +++++----- src/ecpool_worker.erl | 24 +++++++++++++++++------- src/ecpool_worker_sup.erl | 6 +----- 6 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/ecpool.app.src b/src/ecpool.app.src index db637ed4e..e5e02a8e7 100644 --- a/src/ecpool.app.src +++ b/src/ecpool.app.src @@ -1,7 +1,7 @@ {application, ecpool, [ {description, "Erlang Client/Connection Pool"}, - {vsn, "0.1"}, + {vsn, "0.2"}, {registered, []}, {applications, [ kernel, diff --git a/src/ecpool.erl b/src/ecpool.erl index 8fc2c7d24..97668c06f 100644 --- a/src/ecpool.erl +++ b/src/ecpool.erl @@ -19,31 +19,38 @@ %%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE %%% SOFTWARE. %%%----------------------------------------------------------------------------- -%%% @doc ecpool API. +%%% @doc ecpool Main API. %%% %%% @author Feng Lee %%%----------------------------------------------------------------------------- -module(ecpool). --export([name/1, start_pool/3, with_client/2, with_client/3, stop_pool/1]). - -name(Pool) -> - {?MODULE, Pool}. +-export([start_pool/3, start_sup_pool/3, stop_sup_pool/1, + with_client/2, with_client/3, name/1, workers/1]). +%% @doc Start the pool +-spec start_pool(atom(), atom(), list()) -> {ok, pid()} | {error, any()}. start_pool(Pool, Mod, Opts) when is_atom(Pool) -> ecpool_pool_sup:start_link(Pool, Mod, Opts). -stop_pool(Pool) when is_atom(Pool) -> +%% @doc Start the pool supervised by ecpool_sup +start_sup_pool(Pool, Mod, Opts) when is_atom(Pool) -> + ecpool_sup:start_pool(Pool, Mod, Opts). + +%% @doc Start the pool supervised by ecpool_sup +stop_sup_pool(Pool) when is_atom(Pool) -> ecpool_sup:stop_pool(Pool). +%% @doc Call the fun with client/connection +-spec with_client(atom(), fun((Client :: pid()) -> any())) -> any(). with_client(Pool, Fun) when is_atom(Pool) -> - Worker = gproc_pool:pick_worker({?MODULE, Pool}), - with_worker(Worker, Fun). + with_worker(gproc_pool:pick_worker(name(Pool)), Fun). +%% @doc Call the fun with client/connection +-spec with_client(atom(), any(), fun((Client :: pid()) -> any())) -> any(). with_client(Pool, Key, Fun) when is_atom(Pool) -> - Worker = gproc_pool:pick_worker({?MODULE, Pool}, Key), - with_worker(Worker, Fun). + with_worker(gproc_pool:pick_worker(name(Pool), Key), Fun). with_worker(Worker, Fun) -> case ecpool_worker:client(Worker) of @@ -51,3 +58,9 @@ with_worker(Worker, Fun) -> {error, Reason} -> {error, Reason} end. +%% @doc ecpool name +name(Pool) -> {?MODULE, Pool}. + +%% @doc pool workers +workers(Pool) -> gproc_pool:active_workers(name(Pool)). + diff --git a/src/ecpool_pool.erl b/src/ecpool_pool.erl index c55f38e9f..0bb1a780e 100644 --- a/src/ecpool_pool.erl +++ b/src/ecpool_pool.erl @@ -78,11 +78,9 @@ ensure_pool_worker(Pool, Name, Slot) -> error:exists -> ok end. -handle_call(info, _From, State = #state{name = Pool, size = Size, - type = Type}) -> - Workers = gproc_pool:active_workers(ecpool:name(Pool)), +handle_call(info, _From, State = #state{name = Pool, size = Size, type = Type}) -> Info = [{pool_name, Pool}, {pool_size, Size}, - {pool_type, Type}, {workers, Workers}], + {pool_type, Type}, {workers, ecpool:workers(Pool)}], {reply, Info, State}; handle_call(_Request, _From, State) -> diff --git a/src/ecpool_sup.erl b/src/ecpool_sup.erl index 196f54fc1..0eb371816 100644 --- a/src/ecpool_sup.erl +++ b/src/ecpool_sup.erl @@ -35,7 +35,7 @@ -export([init/1]). %% @doc Start supervisor. --spec start_link() -> {ok, pid()}. +-spec start_link() -> {ok, pid()} | {error, any()}. start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). @@ -46,10 +46,10 @@ start_pool(Pool, Mod, Opts) when is_atom(Pool) -> stop_pool(Pool) when is_atom(Pool) -> ChildId = child_id(Pool), case supervisor:terminate_child(?MODULE, ChildId) of - ok -> - supervisor:delete_child(?MODULE, ChildId); - {error, Reason} -> - {error, Reason} + ok -> + supervisor:delete_child(?MODULE, ChildId); + {error, Reason} -> + {error, Reason} end. %% @doc All Pools supervisored by ecpool_sup. diff --git a/src/ecpool_worker.erl b/src/ecpool_worker.erl index a7e4088ed..d5e25ce52 100644 --- a/src/ecpool_worker.erl +++ b/src/ecpool_worker.erl @@ -29,7 +29,7 @@ -behaviour(gen_server). %% API Function Exports --export([start_link/4, client/1]). +-export([start_link/4, client/1, is_connected/1]). %% gen_server Function Exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -69,7 +69,13 @@ start_link(Pool, Id, Mod, Opts) -> %% @doc Get client/connection. -spec client(pid()) -> undefined | pid(). -client(Pid) -> gen_server:call(Pid, client, infinity). +client(Pid) -> + gen_server:call(Pid, client, infinity). + +%% @doc Is client connected? +-spec is_connected(pid()) -> boolean(). +is_connected(Pid) -> + gen_server:call(Pid, is_connected). %%%============================================================================= %%% gen_server callbacks @@ -86,6 +92,9 @@ init([Pool, Id, Mod, Opts]) -> {stop, Error} end. +handle_call(is_connected, _From, State = #state{client = Client}) -> + {reply, Client =/= undefined andalso is_process_alive(Client), State}; + handle_call(client, _From, State = #state{client = undefined}) -> {reply, {error, disconnected}, State}; @@ -100,8 +109,7 @@ handle_info({'EXIT', Pid, Reason}, State = #state{client = Pid, opts = Opts}) -> false -> {stop, Reason, State}; Secs -> - erlang:send_after(timer:seconds(Secs), self(), reconnect), - {noreply, State#state{client = undefined}} + reconnect(Secs, State) end; handle_info(reconnect, State = #state{opts = Opts}) -> @@ -109,9 +117,7 @@ handle_info(reconnect, State = #state{opts = Opts}) -> {ok, Client} -> {noreply, State#state{client = Client}}; {error, _Error} -> - Secs = proplists:get_value(auto_reconnect, Opts), - erlang:send_after(timer:seconds(Secs), self(), reconnect), - {noreply, State#state{client = undefined}} + reconnect(proplists:get_value(auto_reconnect, Opts), State) end; handle_info(_Info, State) -> @@ -141,3 +147,7 @@ connopts([{auto_reconnect, _} | Opts], Acc) -> connopts([Opt | Opts], Acc) -> connopts(Opts, [Opt | Acc]). +reconnect(Secs, State) -> + erlang:send_after(timer:seconds(Secs), self(), reconnect), + {noreply, State#state{client = undefined}}. + diff --git a/src/ecpool_worker_sup.erl b/src/ecpool_worker_sup.erl index 2d50bd7e9..c2083e236 100644 --- a/src/ecpool_worker_sup.erl +++ b/src/ecpool_worker_sup.erl @@ -28,15 +28,11 @@ -behaviour(supervisor). --export([start_link/3, workers/1, init/1]). +-export([start_link/3, init/1]). start_link(Pool, Mod, Opts) when is_atom(Pool) -> supervisor:start_link(?MODULE, [Pool, Mod, Opts]). -workers(WorkerSup) -> - [{ChildId, Pid} || {ChildId, Pid, worker, _} - <- supervisor:which_children(WorkerSup)]. - init([Pool, Mod, Opts]) -> WorkerSpec = fun(Id) -> {{worker, Id}, {ecpool_worker, start_link, [Pool, Id, Mod, Opts]},