Browse Source

Make member start timeout configurable per pool

The time allowed for a member to start can be configured via
`{member_start_timeout, {1, min}}` in the per-pool config. The default
is one minute.
Seth Falcon 12 years ago
parent
commit
25479472d5
3 changed files with 19 additions and 9 deletions
  1. 14 8
      src/pooler.erl
  2. 3 0
      src/pooler.hrl
  3. 2 1
      src/pooler_config.erl

+ 14 - 8
src/pooler.erl

@@ -107,6 +107,9 @@ manual_start() ->
 %% 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'.</dd>
+%% <dt>`member_start_timeout'</dt>
+%% <dd>Time limit for member starts. Specified as `{Time,
+%% Unit}'. Defaults to `{1, min}'.</dd>
 %% </dl>
 new_pool(PoolConfig) ->
     pooler_sup:new_pool(PoolConfig).
@@ -318,11 +321,12 @@ do_accept_member({Ref, Pid},
                     all_members = AllMembers,
                     free_pids = Free,
                     free_count = NumFree,
-                    starting_members = StartingMembers0
+                    starting_members = StartingMembers0,
+                    member_start_timeout = StartTimeout
                    } = Pool) when is_pid(Pid) ->
     %% make sure we don't accept a timedout member
     StartingMembers = remove_stale_starting_members(Pool, StartingMembers0,
-                                                    ?DEFAULT_MEMBER_START_TIMEOUT),
+                                                    StartTimeout),
     case lists:keymember(Ref, 1, StartingMembers) of
         false ->
             %% a pid we didn't ask to start, ignore it.
@@ -338,10 +342,11 @@ do_accept_member({Ref, Pid},
                       all_members = AllMembers1,
                       starting_members = StartingMembers1}
     end;
-do_accept_member({Ref, _Reason}, #pool{starting_members = StartingMembers0} = Pool) ->
+do_accept_member({Ref, _Reason}, #pool{starting_members = StartingMembers0,
+                                       member_start_timeout = StartTimeout} = Pool) ->
     %% member start failed, remove in-flight ref and carry on.
     StartingMembers = remove_stale_starting_members(Pool, StartingMembers0,
-                                                    ?DEFAULT_MEMBER_START_TIMEOUT),
+                                                    StartTimeout),
     StartingMembers1 = lists:keydelete(Ref, 1, StartingMembers),
     Pool#pool{starting_members = StartingMembers1}.
 
@@ -382,8 +387,8 @@ init_members_sync(N, #pool{name = PoolName} = Pool) ->
 
 collect_init_members(#pool{starting_members = []} = Pool) ->
     Pool;
-collect_init_members(#pool{} = Pool) ->
-    Timeout = time_as_millis(?DEFAULT_MEMBER_START_TIMEOUT),
+collect_init_members(#pool{member_start_timeout = StartTimeout} = Pool) ->
+    Timeout = time_as_millis(StartTimeout),
     receive
         {accept_member, {Ref, Member}} ->
             collect_init_members(do_accept_member({Ref, Member}, Pool))
@@ -400,11 +405,12 @@ take_member_from_pool(#pool{init_count = InitCount,
                             in_use_count = NumInUse,
                             free_count = NumFree,
                             consumer_to_pid = CPMap,
-                            starting_members = StartingMembers0} = Pool,
+                            starting_members = StartingMembers0,
+                            member_start_timeout = StartTimeout} = Pool,
                       From) ->
     send_metric(Pool, take_rate, 1, meter),
     StartingMembers = remove_stale_starting_members(Pool, StartingMembers0,
-                                                    ?DEFAULT_MEMBER_START_TIMEOUT),
+                                                    StartTimeout),
     NumCanAdd = Max - (NumInUse + NumFree + length(StartingMembers)),
     case Free of
         [] when NumCanAdd =< 0  ->

+ 3 - 0
src/pooler.hrl

@@ -60,6 +60,9 @@
           %% and is used to implement start timeout.
           starting_members = [] :: [{reference(), erlang:timestamp()}],
 
+          %% The maximum amount of time to allow for member start.
+          member_start_timeout = ?DEFAULT_MEMBER_START_TIMEOUT :: time_spec(),
+
           %% The module to use for collecting metrics. If set to
           %% 'pooler_no_metrics', then metric sending calls do
           %% nothing. A typical value to actually capture metrics is

+ 2 - 1
src/pooler_config.erl

@@ -1,5 +1,5 @@
 %% @author Seth Falcon <seth@userprimary.net>
-%% @copyright 2012 Seth Falcon
+%% @copyright 2012-2013 Seth Falcon
 %% @doc Helper module to transform app config proplists into pool records
 
 -module(pooler_config).
@@ -19,6 +19,7 @@ list_to_pool(P) ->
        add_member_retry  = ?gv(add_member_retry, P, ?DEFAULT_ADD_RETRY),
        cull_interval     = ?gv(cull_interval, P, ?DEFAULT_CULL_INTERVAL),
        max_age           = ?gv(max_age, P, ?DEFAULT_MAX_AGE),
+       member_start_timeout = ?gv(member_start_timeout, P, ?DEFAULT_MEMBER_START_TIMEOUT),
        metrics_mod       = ?gv(metrics_mod, P, pooler_no_metrics)}.
 
 %% Return `Value' for `Key' in proplist `P' or crashes with an