pooler.hrl 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. -define(DEFAULT_ADD_RETRY, 1).
  2. -define(DEFAULT_CULL_INTERVAL, {1, min}).
  3. -define(DEFAULT_MAX_AGE, {30, sec}).
  4. -define(DEFAULT_MEMBER_START_TIMEOUT, {1, min}).
  5. -define(DEFAULT_AUTO_GROW_THRESHOLD, undefined).
  6. -define(POOLER_GROUP_TABLE, pooler_group_table).
  7. -define(DEFAULT_POOLER_QUEUE_MAX, 50).
  8. -define(POOLER_PID, '$pooler_pid').
  9. -define(DEFAULT_STOP_MFA, {erlang, exit, [?POOLER_PID, kill]}).
  10. -type member_info() :: {string(), free | pid(), {_, _, _}}.
  11. -type free_member_info() :: {string(), free, {_, _, _}}.
  12. -type time_unit() :: min | sec | ms | mu.
  13. -type time_spec() :: {non_neg_integer(), time_unit()}.
  14. -ifdef(namespaced_types).
  15. -type p_dict() :: dict:dict().
  16. -type p_requestor_queue() :: queue:queue({{pid(), _}, timer:tref()}).
  17. -else.
  18. -type p_dict() :: dict().
  19. -type p_requestor_queue() :: queue().
  20. -endif.
  21. -record(pool, {
  22. name :: atom(),
  23. group :: atom(),
  24. max_count = 100 :: non_neg_integer(),
  25. init_count = 10 :: non_neg_integer(),
  26. start_mfa :: {atom(), atom(), [term()]},
  27. free_pids = [] :: [pid()],
  28. in_use_count = 0 :: non_neg_integer(),
  29. free_count = 0 :: non_neg_integer(),
  30. %% The number times to attempt adding a pool member if the
  31. %% pool size is below max_count and there are no free
  32. %% members. After this many tries, error_no_members will be
  33. %% returned by a call to take_member. NOTE: this value
  34. %% should be >= 2 or else the pool will not grow on demand
  35. %% when max_count is larger than init_count.
  36. add_member_retry = ?DEFAULT_ADD_RETRY :: non_neg_integer(),
  37. %% The interval to schedule a cull message. Both
  38. %% 'cull_interval' and 'max_age' are specified using a
  39. %% `time_spec()' type.
  40. cull_interval = ?DEFAULT_CULL_INTERVAL :: time_spec(),
  41. %% The maximum age for members.
  42. max_age = ?DEFAULT_MAX_AGE :: time_spec(),
  43. %% The supervisor used to start new members
  44. member_sup :: atom() | pid(),
  45. %% The supervisor used to start starter servers that start
  46. %% new members. This is what enables async member starts.
  47. starter_sup :: atom() | pid(),
  48. %% Maps member pid to a tuple of the form:
  49. %% {MonitorRef, Status, Time},
  50. %% where MonitorRef is a monitor reference for the member,,
  51. %% Status is either 'free' or the consumer pid, and Time is
  52. %% an Erlang timestamp that records when the member became
  53. %% free.
  54. all_members = dict:new() :: p_dict(),
  55. %% Maps consumer pid to a tuple of the form:
  56. %% {MonitorRef, MemberList} where MonitorRef is a monitor
  57. %% reference for the consumer and MemberList is a list of
  58. %% members being consumed.
  59. consumer_to_pid = dict:new() :: p_dict(),
  60. %% A list of `{References, Timestamp}' tuples representing
  61. %% new member start requests that are in-flight. The
  62. %% timestamp records when the start request was initiated
  63. %% and is used to implement start timeout.
  64. starting_members = [] :: [{reference(), erlang:timestamp()}],
  65. %% The maximum amount of time to allow for member start.
  66. member_start_timeout = ?DEFAULT_MEMBER_START_TIMEOUT :: time_spec(),
  67. %% The optional threshold at which more members will be started if
  68. %% free_count drops to this value. Normally undefined, but may be
  69. %% set to a non-negative integer in order to enable "anticipatory"
  70. %% behavior (start members before they're actually needed).
  71. auto_grow_threshold = ?DEFAULT_AUTO_GROW_THRESHOLD :: undefined | non_neg_integer(),
  72. %% Stop callback to gracefully attempt to terminate pool members.
  73. %% The list of arguments must contain the fixed atom '$pooler_pid'.
  74. stop_mfa = ?DEFAULT_STOP_MFA :: {atom(), atom(), [term()]},
  75. %% The module to use for collecting metrics. If set to
  76. %% 'pooler_no_metrics', then metric sending calls do
  77. %% nothing. A typical value to actually capture metrics is
  78. %% folsom_metrics.
  79. metrics_mod = pooler_no_metrics :: atom(),
  80. %% The API used to call the metrics system. It supports both Folsom
  81. %% and Exometer format.
  82. metrics_api = folsom :: 'folsom' | 'exometer',
  83. %% A queue of requestors for blocking take member requests
  84. queued_requestors = queue:new() :: p_requestor_queue(),
  85. %% The max depth of the queue
  86. queue_max = 50
  87. }).
  88. -define(gv(X, Y), proplists:get_value(X, Y)).
  89. -define(gv(X, Y, D), proplists:get_value(X, Y, D)).