4.2.19. Poolboy [1]¶
A hunky Erlang worker pool factory
用法:
1> Worker = poolboy:checkout(PoolName).
<0.9001.0>
2> gen_server:call(Worker, Request).
ok
3> poolboy:checkin(PoolName, Worker).
ok
选项:
name`` the pool name
worker_module`` the module that represents the workers
size`` the maximum pool size
max_overflow`` the maximum number of workers created if pool is empty
example.app:
1{application, example, [
2 {description, "An example application"},
3 {vsn, "0.1"},
4 {applications, [kernel, stdlib, sasl, crypto, ssl]},
5 {modules, [example, example_worker]},
6 {registered, [example]},
7 {mod, {example, []}},
8 {env, [
9 {pools, [
10 {pool1, [
11 {size, 10},
12 {max_overflow, 20}
13 ], [
14 {hostname, "127.0.0.1"},
15 {database, "db1"},
16 {username, "db1"},
17 {password, "abc123"}
18 ]
19 },
20 {pool2, [
21 {size, 5},
22 {max_overflow, 10}
23 ], [
24 {hostname, "127.0.0.1"},
25 {database, "db2"},
26 {username, "db2"},
27 {password, "abc123"}
28 ]
29 }
30 ]}
31 ]}
32]}.
example.erl:
1-module(example).
2-behaviour(application).
3-behaviour(supervisor).
4
5-export([start/0, stop/0, squery/2, equery/3]).
6-export([start/2, stop/1]).
7-export([init/1]).
8
9start() ->
10 application:start(?MODULE).
11
12stop() ->
13 application:stop(?MODULE).
14
15start(_Type, _Args) ->
16 supervisor:start_link({local, example_sup}, ?MODULE, []).
17
18stop(_State) ->
19 ok.
20
21init([]) ->
22 {ok, Pools} = application:get_env(example, pools),
23 PoolSpecs = lists:map(fun({Name, SizeArgs, WorkerArgs}) ->
24 PoolArgs = [
25 {name, {local, Name}},
26 {worker_module, example_worker}
27 ] ++ SizeArgs,
28 poolboy:child_spec(Name, PoolArgs, WorkerArgs)
29 end, Pools),
30 {ok, {{one_for_one, 10, 10}, PoolSpecs}}.
31
32squery(PoolName, Sql) ->
33 poolboy:transaction(PoolName, fun(Worker) ->
34 gen_server:call(Worker, {squery, Sql})
35 end).
36
37equery(PoolName, Stmt, Params) ->
38 poolboy:transaction(PoolName, fun(Worker) ->
39 gen_server:call(Worker, {equery, Stmt, Params})
40 end).
example_worker.erl:
1-module(example_worker).
2-behaviour(gen_server).
3-behaviour(poolboy_worker).
4
5-export([start_link/1]).
6-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
7 code_change/3]).
8
9-record(state, {conn}).
10
11start_link(Args) ->
12 gen_server:start_link(?MODULE, Args, []).
13
14init(Args) ->
15 Hostname = proplists:get_value(hostname, Args),
16 Database = proplists:get_value(database, Args),
17 Username = proplists:get_value(username, Args),
18 Password = proplists:get_value(password, Args),
19 {ok, Conn} = pgsql:connect(Hostname, Username, Password, [
20 {database, Database}
21 ]),
22 {ok, #state{conn=Conn}}.
23
24handle_call({squery, Sql}, _From, #state{conn=Conn}=State) ->
25 {reply, pgsql:squery(Conn, Sql), State};
26handle_call(handle_call({equery, Stmt, Params}, _From, #state{conn=Conn}=State) ->
27 {reply, pgsql:equery(Conn, Stmt, Params), State};
28handle_call(_Request, _From, State) ->
29 {reply, ok, State}.
30
31handle_cast(_Msg, State) ->
32 {noreply, State}.
33
34handle_info(_Info, State) ->
35 {noreply, State}.
36
37terminate(_Reason, #state{conn=Conn}) ->
38 ok = pgsql:close(Conn),
39 ok.
40
41code_change(_OldVsn, State, _Extra) ->
42 {ok, State}.) ->