在hottub和poolboy之间纠结,后来发现hottub在子进程crash以后,重启会有问题,尝试用了下poolboy,发现可以满足需求,在此记录下
poolboy官网的和pgsql结合的例子在我这边总是崩溃,提示invalid child spec,无奈,google后,在某个角落找到一个可以跑的例子,改了下,贴一下备忘
新建工程rebar-creator create-app pool_test
config.erl
-module(config). -compile(export_all). -export([]). get_pool_name()-> test_pool. get_pool_args()-> PoolArgs = [{name, {local, get_pool_name()}}, {worker_module, test_worker}, {size, 5}, {max_overflow, 10}], PoolArgs. get_worker_args()-> test_work_args.
pool_sup.erl
-module(pool_sup). -behaviour(supervisor). -export([start_link/0]). -export([init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> RestartStrategy = one_for_one, MaxRestarts = 100, MaxSecondsBetweenRestarts = 10, SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts}, %% Restart = permanent, Restart = transient, Shutdown = 5000, Type = supervisor, Child = {worker_sup, {worker_sup, start_link, []}, Restart, Shutdown, Type, [worker_sup]}, Children = [Child], {ok, {SupFlags, Children}}.
pool_test_app.erl
-module(pool_test_app). -behaviour(application). -compile(export_all). start(_StartType, _StartArgs) -> pool_sup:start_link(). stop(_State) -> ok. get_worker() -> poolboy:checkout(test_pool). info(Pid) -> gen_server:call(Pid, {info}). crash(Pid) -> gen_server:call(Pid, {crash}).
test_worker.erl
-module(test_worker). -behaviour(gen_server). -behaviour(poolboy_worker). -export([start_link/1]). -export([init/1, handle_call/3, handle_cast/2,handle_info/2, terminate/2, code_change/3]). -record(state, {}). start_link([Args]) -> gen_server:start_link(?MODULE, [Args], []). init([Args]) -> io:format("working thread init ~p,~p~n", [self(), Args]), process_flag(trap_exit, true), {ok, #state{}}. handle_call({info}, _From, State) -> io:format("info~n"), {reply, _Reply = ok, State}; handle_call({crash}, _From, State) -> 1 = 2, {reply, _Reply = ok, State}; handle_call(_Request, _From, State) -> {reply, _Reply = ok, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info({'EXIT', _Pid, Reason}, State) -> io:format("exit reason ~p~n", [Reason]), case Reason of normal -> io:format("normal exit trapped~n"), {stop, normal, State}; other -> io:format("other exit trapped~n"), {noreply, State} end; handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> io:format("terminate ~p,~p,~p~n", [_Reason, _State, self()]), ok. code_change(_OldVsn, State, _Extra) -> {ok, State}.
worker_sup.erl
-module(worker_sup). -behaviour(supervisor). -export([start_link/0, init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). %% {ok,{{one_for_one,1000,3600}, %% [{test_pool,{poolboy,start_link, %% [[{name,{local,test_pool}}, %% {worker_module,test_worker}, %% {size,5}, %% {max_overflow,10}], %% [test_work_args]]}, %% permanent,5000,worker, %% [poolboy]}]}} %init返回的策略里面的回调函数是poolboy,start_link,所以,不需要手工去启动poolboy init([]) -> Name = config:get_pool_name(), PoolArgs = config:get_pool_args(), WorkerArgs = config:get_worker_args(), PoolSpec = poolboy:child_spec(Name, PoolArgs, [WorkerArgs]), ChildSpecs = [PoolSpec], {ok, {{one_for_one, 1000, 3600}, ChildSpecs}}.
大概就这样,子进程crash了自动重启,pool crash了也自动重启。满足需求了