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
label_spec() = {Name::atom(), label_values()}
label_values() = any | [atom()]
member_expiry() = integer() | infinity
erlang:monotonic_time(millisecond) deadline, or infinity when TTL is disabled.
member_info() = {reference(), member_status(), erlang:timestamp(), member_expiry()}
See pool_stats/1
member_status() = free | pid() | {stopping, replace | no_replace}
metric_info() = #{name := metric_name(), type := metric_type(), help := binary(), labels := [label_spec()]}
metric_name() = take | free | in_use | stopping | queue | error_no_members | killed_free | killed_in_use | queue_max_reached | starting_member_timeout
metric_type() = counter | gauge | histogram | history | meter
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 | telemetry, metrics_mod => module(), stop_mfa => pooler_starter:stop_mfa(), initialize_mfa => {module(), atom(), ['$pooler_pid' | '$pooler_pool_name' | any(), ...]}, auto_grow_threshold => non_neg_integer(), add_member_retry => non_neg_integer(), max_lifetime => time_spec(), max_lifetime_jitter => time_spec()}
pool_config_legacy() = [{atom(), any()}]
Can be provided as a proplist, but is not recommended
pool_name() = atom()
The name of the pool
reconfigure_action() = {start_workers, pos_integer()} | {stop_free_workers, pos_integer()} | {shrink_queue, pos_integer()} | {reset_cull_timer, time_spec()} | {cull, term()} | {leave_group, group_name()} | {join_group, group_name()} | {set_parameter, {group, group_name() | undefined} | {init_count, non_neg_integer()} | {max_count, non_neg_integer()} | {cull_interval, time_spec()} | {max_age, time_spec()} | {member_start_timeout, time_spec()} | {queue_max, non_neg_integer()} | {metrics_api, folsom | exometer | telemetry} | {metrics_mod, module()} | {stop_mfa, pooler_starter:stop_mfa()} | {initialize_mfa, undefined | {module(), atom(), ['$pooler_pid' | '$pooler_pool_name' | any(), ...]}} | {auto_grow_threshold, non_neg_integer()}} | {update_ttl, undefined | #ttl{max_lifetime = time_spec(), jitter = time_spec(), timer = reference() | undefined, timer_target = pid() | undefined}}
time_spec() = {non_neg_integer(), time_unit()} | non_neg_integer()
Time value: either a {Amount, Unit} tuple or a plain non-negative integer
(interpreted as milliseconds, consistent with Erlang timeout conventions).
time_unit() = hour | 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 | |
| metrics/0 | Returns descriptors for all metrics emitted by pooler when metrics_api = telemetry. |
| new_pool/1 | Start a new pool described by the map PoolConfig. |
| pool_child_spec/1 | Get child spec described by the PoolConfig. |
| pool_reconfigure/2 | Updates the pool's state so it starts to behave like it was started with the new configuration without restart. |
| 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
Res = [{ok, term()} | {error, term()}]
Invokes Fun with arity 1 over all free members in pool with PoolName.
call_free_members(PoolName::pool_name() | pid(), Fun, Timeout::timeout()) -> Res
Fun = fun((pid()) -> term())Res = [{ok, term()} | {error, term()}]
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(), OldState::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()
metrics() -> [metric_info()]
Returns descriptors for all metrics emitted by pooler when metrics_api = telemetry.
Each descriptor is a map with keys name, type, help, and labels.
name is the atom used in the telemetry event name [pooler, Name].
labels is a proplist [{LabelName, LabelValues}] where LabelValues is
any for open-ended values or a list of the known atoms.
The order of entries in labels matches the positional label order expected by prometheus.erl.
[declare(M) || M <- pooler:metrics()]Note: for gauge-type metrics (
free, in_use, stopping, queue), consider using
pool_utilization/1 with a prometheus_collector instead — it reads current values
on each scrape rather than relying on push events from take/return calls.
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:
nameinit_countinit_count members will be started in parallel.max_countstart_mfa{Mod, Fun, Args} describing how to start
new pool members.In addition, you can specify any of the following optional configuration options:
groupgroup 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
a {Time, Unit} tuple where Unit is one of hour, min, sec, ms, mu,
or as a plain non-negative integer (milliseconds).
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_maxtake_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_membersmetrics_api, metrics_modfolsom
or API similar to exometer. Use metrics_api to specify API style and metrics_mod to specify
the module implementing this API.stop_mfapooler 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_thresholdundefined (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.max_lifetimeundefined (disabled). Maximum wall-clock lifetime of a pool member, specified as
{Time, Unit}. When a member reaches its lifetime it is stopped and replaced with a fresh one.
Eviction happens proactively via a timer while the member is idle, inline at the next
take_member/1 call if the timer fires late, or at return_member/2 if the
member expired while in use. Members held by a consumer past their TTL are never forcibly
evicted. Useful when firewalls or database backends impose hard TCP connection lifetime limits.
Has zero per-operation overhead when not set.max_lifetime_jitter{0, sec} (no jitter). Random spread applied to each member's expiry time,
specified as {Time, Unit}. Each member's lifetime is offset by a value drawn uniformly
from [-jitter, +jitter], so members started together do not all expire simultaneously.
Only meaningful when max_lifetime is set. Must be strictly less than max_lifetime;
pool start and reconfigure will fail with jitter_must_be_less_than_max_lifetime otherwise.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_reconfigure(Pool::pool_name() | pid(), NewConfig::pool_config()) -> {ok, [reconfigure_action()]} | {error, any()}
Updates the pool's state so it starts to behave like it was started with the new configuration without restart
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()} | {stopping_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