diff options
author | Calvin Morrison <calvin@pobox.com> | 2025-09-03 21:15:36 -0400 |
---|---|---|
committer | Calvin Morrison <calvin@pobox.com> | 2025-09-03 21:15:36 -0400 |
commit | 49fa5aa2a127bdf8924d02bf77e5086b39c7a447 (patch) | |
tree | 61d86a7705dacc9fddccc29fa79d075d83ab8059 /server/_build/default/lib/poolboy/README.md |
Diffstat (limited to 'server/_build/default/lib/poolboy/README.md')
-rw-r--r-- | server/_build/default/lib/poolboy/README.md | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/server/_build/default/lib/poolboy/README.md b/server/_build/default/lib/poolboy/README.md new file mode 100644 index 0000000..495d812 --- /dev/null +++ b/server/_build/default/lib/poolboy/README.md @@ -0,0 +1,171 @@ +# Poolboy - A hunky Erlang worker pool factory + +[](https://travis-ci.org/devinus/poolboy) + +[](https://gratipay.com/devinus/) + +Poolboy is a **lightweight**, **generic** pooling library for Erlang with a +focus on **simplicity**, **performance**, and **rock-solid** disaster recovery. + +## Usage + +```erl-sh +1> Worker = poolboy:checkout(PoolName). +<0.9001.0> +2> gen_server:call(Worker, Request). +ok +3> poolboy:checkin(PoolName, Worker). +ok +``` + +## Example + +This is an example application showcasing database connection pools using +Poolboy and [epgsql](https://github.com/epgsql/epgsql). + +### example.app + +```erlang +{application, example, [ + {description, "An example application"}, + {vsn, "0.1"}, + {applications, [kernel, stdlib, sasl, crypto, ssl]}, + {modules, [example, example_worker]}, + {registered, [example]}, + {mod, {example, []}}, + {env, [ + {pools, [ + {pool1, [ + {size, 10}, + {max_overflow, 20} + ], [ + {hostname, "127.0.0.1"}, + {database, "db1"}, + {username, "db1"}, + {password, "abc123"} + ]}, + {pool2, [ + {size, 5}, + {max_overflow, 10} + ], [ + {hostname, "127.0.0.1"}, + {database, "db2"}, + {username, "db2"}, + {password, "abc123"} + ]} + ]} + ]} +]}. +``` + +### example.erl + +```erlang +-module(example). +-behaviour(application). +-behaviour(supervisor). + +-export([start/0, stop/0, squery/2, equery/3]). +-export([start/2, stop/1]). +-export([init/1]). + +start() -> + application:start(?MODULE). + +stop() -> + application:stop(?MODULE). + +start(_Type, _Args) -> + supervisor:start_link({local, example_sup}, ?MODULE, []). + +stop(_State) -> + ok. + +init([]) -> + {ok, Pools} = application:get_env(example, pools), + PoolSpecs = lists:map(fun({Name, SizeArgs, WorkerArgs}) -> + PoolArgs = [{name, {local, Name}}, + {worker_module, example_worker}] ++ SizeArgs, + poolboy:child_spec(Name, PoolArgs, WorkerArgs) + end, Pools), + {ok, {{one_for_one, 10, 10}, PoolSpecs}}. + +squery(PoolName, Sql) -> + poolboy:transaction(PoolName, fun(Worker) -> + gen_server:call(Worker, {squery, Sql}) + end). + +equery(PoolName, Stmt, Params) -> + poolboy:transaction(PoolName, fun(Worker) -> + gen_server:call(Worker, {equery, Stmt, Params}) + end). +``` + +### example_worker.erl + +```erlang +-module(example_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, {conn}). + +start_link(Args) -> + gen_server:start_link(?MODULE, Args, []). + +init(Args) -> + process_flag(trap_exit, true), + Hostname = proplists:get_value(hostname, Args), + Database = proplists:get_value(database, Args), + Username = proplists:get_value(username, Args), + Password = proplists:get_value(password, Args), + {ok, Conn} = epgsql:connect(Hostname, Username, Password, [ + {database, Database} + ]), + {ok, #state{conn=Conn}}. + +handle_call({squery, Sql}, _From, #state{conn=Conn}=State) -> + {reply, epgsql:squery(Conn, Sql), State}; +handle_call({equery, Stmt, Params}, _From, #state{conn=Conn}=State) -> + {reply, epgsql:equery(Conn, Stmt, Params), State}; +handle_call(_Request, _From, State) -> + {reply, ok, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, #state{conn=Conn}) -> + ok = epgsql:close(Conn), + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. +``` + +## Options + +- `name`: the pool name +- `worker_module`: the module that represents the workers +- `size`: maximum pool size +- `max_overflow`: maximum number of workers created if pool is empty +- `strategy`: `lifo` or `fifo`, determines whether checked in workers should be + placed first or last in the line of available workers. So, `lifo` operates like a traditional stack; `fifo` like a queue. Default is `lifo`. + +## Authors + +- Devin Torres (devinus) <devin@devintorres.com> +- Andrew Thompson (Vagabond) <andrew@hijacked.us> +- Kurt Williams (onkel-dirtus) <kurt.r.williams@gmail.com> + +## License + +Poolboy is available in the public domain (see `UNLICENSE`). +Poolboy is also optionally available under the ISC license (see `LICENSE`), +meant especially for jurisdictions that do not recognize public domain works. |