Copyright © 2011-2013 Seth Falcon
Behaviours: gen_server.
Authors: Seth Falcon (seth@userprimary.net).
This is the main interface to the pooler application
To integrate with your application, you probably want to callapplication:start(pooler)
after having specified appropriate
configuration for the pooler application (either via a config file
or appropriate calls to the application module to set the
application's config).
group_name() = atom()
The name of the group pool belongs to
member_info() = {reference(), free | pid(), erlang:timestamp()}
See pool_stats/1
pool_config() = #{name := pool_name(), init_count := non_neg_integer(), max_count := non_neg_integer(), start_mfa := {module(), atom(), [any()]}, group => group_name(), cull_interval => time_spec(), max_age => time_spec(), member_start_timeout => time_spec(), queue_max => non_neg_integer(), metrics_api => folsom | exometer, metrics_mod => module(), stop_mfa => {module(), atom(), ['$pooler_pid' | any(), ...]}, auto_grow_threshold => non_neg_integer(), add_member_retry => non_neg_integer()}
pool_config_legacy() = [{atom(), any()}]
Can be provided as a proplist, but is not recommended
pool_name() = atom()
The name of the pool
time_spec() = {non_neg_integer(), time_unit()}
Human-friendly way to specify the amount of time
time_unit() = min | sec | ms | mu
accept_member/2 | For INTERNAL use. |
call_free_members/2 | Invokes Fun with arity 1 over all free members in pool with PoolName . |
call_free_members/3 | Invokes Fun with arity 1 over all free members in pool with PoolName . |
code_change/3 | |
group_pools/1 | Obtain the pids of all pools which are members of the group. |
handle_call/3 | |
handle_cast/2 | |
handle_continue/2 | |
handle_info/2 | |
init/1 | |
manual_start/0 | |
new_pool/1 | Start a new pool described by the map PoolConfig . |
pool_child_spec/1 | Get child spec described by the PoolConfig . |
pool_stats/1 | Obtain runtime state info for all workers. |
pool_utilization/1 | Obtain utilization info for a pool. |
return_group_member/2 | Return a member that was taken from the group
GroupName . |
return_group_member/3 | Return a member that was taken from the group GroupName . |
return_member/2 | Return a member to the pool so it can be reused. |
return_member/3 | Return a member to the pool so it can be reused. |
rm_group/1 | Terminates the group and all pools in that group. |
rm_pool/1 | Terminate the named pool. |
start/0 | |
start_link/1 | |
stop/0 | |
take_group_member/1 | Take a member from a randomly selected member of the group
GroupName . |
take_member/1 | Obtain exclusive access to a member from PoolName . |
take_member/2 | Obtain exclusive access to a member of 'PoolName'. |
terminate/2 |
accept_member(PoolName::pool_name(), StartResult::pooler_starter:start_result()) -> ok
For INTERNAL use. Adds MemberPid
to the pool.
call_free_members(PoolName::pool_name() | pid(), Fun::fun((pid()) -> term())) -> Res
Invokes Fun
with arity 1 over all free members in pool with PoolName
.
call_free_members(PoolName::pool_name() | pid(), Fun, Timeout::timeout()) -> Res
Invokes Fun
with arity 1 over all free members in pool with PoolName
.
Timeout
sets the timeout of gen_server call.
code_change(OldVsn::term(), State::term(), Extra::term()) -> {ok, term()}
group_pools(GroupName::group_name()) -> [pid()]
Obtain the pids of all pools which are members of the group.
handle_call(Request, From, Pool) -> any()
handle_cast(Msg::term(), Pool::term()) -> {noreply, term()}
handle_continue(X1, Pool) -> any()
handle_info(Info::term(), Pool::term()) -> {noreply, term()}
init(P) -> any()
manual_start() -> any()
new_pool(PoolConfig::pool_config() | pool_config_legacy()) -> {ok, pid()} | {error, {already_started, pid()}}
Start a new pool described by the map PoolConfig
. The
following keys are required in the map:
name
init_count
init_count
members will be started in parallel.max_count
start_mfa
{Mod, Fun, Args}
describing how to start
new pool members.In addition, you can specify any of the following optional configuration options:
group
group
value can be accessed using
take_group_member/1
, return_group_member/2
and group_pools/1
.cull_interval
{1, min}
. Time between checks for stale pool members. Specified as
{Time, Unit}
where Time
is a non-negative integer and Unit
is
one of min
, sec
, ms
, or mu
.
Triggers a once per cull_interval
check to remove members that have not
been accessed in max_age
time units. Culling can be disabled by
specifying a zero time vaule (e.g. {0, min}
). Culling will also be
disabled if init_count
is the same as max_count
.max_age
{30, sec}
. Members idle longer than max_age
time units are removed from
the pool when stale checking is enabled via
cull_interval
. Culling of idle members will never reduce the pool
below init_count
. The value is specified as {Time, Unit}
. Note
that timers are not set on individual pool members and may remain
in the pool beyond the configured max_age
value since members are
only removed on the interval configured via cull_interval
.member_start_timeout
{1, min}
. Time limit for member starts. Specified as {Time, Unit}
.queue_max
take_member/2
), this client will be put into a "waiting queue", served in a FIFO order.
This queue lenght is bound by queue_max
. When queue is full, any new queries will instantly get
error_no_members
metrics_api
, metrics_mod
folsom
or API similar to exometer
. Use metrics_api
to specify API style and metrics_mod
to specify
the module implementing this API.stop_mfa
pooler
needs to terminate one of its workers (when it is returned with fail
status
or max_age
is reached), pooler calls
supervisor:terminate_child(pooler_<pool name>_member_sup, <worker_pid>)
. If worker shutdown requires some
more complex preparatons, a custom stop {Module, Function, Arguments}
callback can be provided.
Arguments
can contain placeholders: $pooler_pool_name
- name of the pool, $pooler_pid
- pid of the worker to
terminate. This callback have to terminate this process and remove it from pooler worker supervisor.auto_grow_threshold
undefined
(disabled). Threshold at which more members (capped to max_count
) will be started
if the number of free workers drops to this value - "anticipatory" behavior (start members before they're
actually needed). Might be usefull when the worker initialization is relatively slow and we want to keep
latency at minimum.pool_child_spec(PoolConfig::pool_config() | pool_config_legacy()) -> supervisor:child_spec()
Get child spec described by the PoolConfig
.
pooler:new_pool/1
for info about PoolConfig
.
pool_stats(PoolName::pool_name() | pid()) -> [{pid(), member_info()}]
Obtain runtime state info for all workers.
Format of the return value is subject to change.pool_utilization(PoolName::pool_name() | pid()) -> [{max_count, pos_integer()} | {in_use_count, non_neg_integer()} | {free_count, non_neg_integer()} | {starting_count, non_neg_integer()} | {queued_count, non_neg_integer()} | {queue_max, non_neg_integer()}]
Obtain utilization info for a pool.
Format of the return value is subject to change, but for now it will be a proplist to maintain backcompat with R16.return_group_member(GroupName::group_name(), MemberPid::pid() | error_no_members) -> ok
Return a member that was taken from the group
GroupName
. This is a convenience function for
return_group_member/3
with Status
of ok
.
return_group_member(GroupName::group_name(), MemberPid::pid() | error_no_members, Status::ok | fail) -> ok
Return a member that was taken from the group GroupName
. If
Status
is ok
the member is returned to the pool from which is
came. If Status
is fail
the member will be terminated and a new
member added to the appropriate pool.
return_member(PoolName::pool_name() | pid(), Pid::pid() | error_no_members) -> ok
Return a member to the pool so it can be reused.
return_member(PoolName::pool_name() | pid(), Pid::pid() | error_no_members, Status::ok | fail) -> ok
Return a member to the pool so it can be reused.
IfStatus
is 'ok', the member is returned to the pool. If
Status
is 'fail', the member is destroyed and a new member is
added to the pool in its place.
rm_group(GroupName::group_name()) -> ok | {error, {failed_rm_pools, [atom()]}}
Terminates the group and all pools in that group.
If termination of any member pool fails, rm_group/1
returns
{error, {failed_delete_pools, Pools}}
, where Pools
is a list
of pools that failed to terminate.
rm_pool(PoolName::pool_name()) -> ok | {error, not_found | running | restarting}
Terminate the named pool.
start() -> ok
start_link(PoolConfig::pool_config()) -> {ok, pid()} | {error, any()}
stop() -> ok
take_group_member(GroupName::group_name()) -> pid() | error_no_members
Take a member from a randomly selected member of the group
GroupName
. Returns MemberPid
or error_no_members
. If no
members are available in the randomly chosen pool, all other pools
in the group are tried in order.
take_member(PoolName::pool_name() | pid()) -> pid() | error_no_members
Obtain exclusive access to a member from PoolName
.
take_member(PoolName::pool_name() | pid(), Timeout::non_neg_integer() | time_spec()) -> pid() | error_no_members
Obtain exclusive access to a member of 'PoolName'.
If no members are available, wait for up to Timeout milliseconds for a member to become available. Waiting requests are served in FIFO order. If no member is available within the specified timeout, error_no_members is returned.Timeout
can be either milliseconds as integer or {duration, time_unit}
terminate(Reason::term(), State::term()) -> ok
Generated by EDoc