Generic connection pool manager for Erlang applications
Erlang
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
include
src
.gitignore
LICENSE
Makefile
README
rebar

README

NOMENCLATURE
------------
Endpoint: A database system, or any other connection-oriented service.


INTRODUCTION
------------
connection_pool is a generic connection pool manager for Erlang applications.

Goals:
- Allow pools to be started by OTP supervisors.
- Assign symbolic names to pools (e.g. 'redis.master', 'redis.slave:0', 'redis.slave:1').
- Return 'dead_enpoint' if all connections to an endpoint go away.  This allows the caller to call another endpoint or return acceptable empty results.
- Try to re-establish dead connections.
- Make it easy to support new types of endpoints.


SUPPORTED ENDPOINT TYPES
------------------------
Currently, the following types of endpoints are supported:

PostgreSQL with epgsql driver (https://github.com/wg/epgsql)

MySQL with http://code.google.com/p/erlang-mysql-driver/ and mysql_conn2.erl (in this package)
NOTE: Don't use MySQL if you have a choice.  Use PostgreSQL.

Redis with Redo driver (https://github.com/JacobVorreuter/redo)
NOTE: If you are using Erldis, we highly recommend using Redo instead.


DEFINING ENDPOINTS
------------------
Example of a set of master-slaves endpoint definitions for Redis:

-define(REDIS_NODES, [
    {'redis:0', [{max_conns, 4}, {'conn_opts', {'192.168.0.10', 6379}}]},
    {'redis:1', [{max_conns, 4}, {'conn_opts', {'192.168.0.11', 6379}}]},
    {'redis:2', [{max_conns, 4}, {'conn_opts', {'192.168.0.12', 6379}}]},
    {'redis:3', [{max_conns, 4}, {'conn_opts', {'192.168.0.13', 6379}}]}
]).


GENERATING CHILD SPECS
----------------------
redo_pool_specs() ->
    [redo_pool:spec(Details) || Details <- ?REDIS_NODES].

% supervisor
init([]) ->
    {ok, {{one_for_one, 3, 40}, redo_pool_specs()}}.


BASIC USAGE
-----------
redis_cmd(PoolName, F) ->
    connection_pool:run({redo_pool, PoolName}, F).

get_foo_bar() ->
    [Foo, Bar] = redis_cmd('default:0', fun(C) ->
        redo:cmd(C, [
            [<<"get">>, <<"foo">>],
            [<<"get">>, <<"bar">>]
        ])
    end).


POSTGRESQL POOL STARTED BY SUPERVISOR
-------------------------------------
psql_pool_specs() ->
    PsqlNodes = [{'db:0', [{max_conns, 2}, {conn_opts, ["127.0.0.1", "user", "pass", [{database, "db0"}]]}]}],
    [psql_pool:spec(Details) || Details <- PsqlNodes].

init([]) ->
    {ok, {{one_for_one, 3, 40}, psql_pool_specs()}}.


POSTGRESQL POOL STARTED DIRECTLY (WITHOUT SUPERVISOR)
-----------------------------------------------------
foo() ->
    [{PoolName, EndpointDetails}] = [{'db:0', [{max_conns, 1}, {conn_opts, ["127.0.0.1", "user", "pass", [{database, "db0"}]]}]}],
    {ok, Pool} = connection_pool:start_link({psql_pool, Name}, Details),
    % do stuff
    connection_pool:close(Pool).