Skip to content

Commit 8ead408

Browse files
committed
Merge branch 'release/v1.2.0' into main
2 parents 63a0596 + 00c53e0 commit 8ead408

19 files changed

+213
-197
lines changed

.github/workflows/ci-tests.yml

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ jobs:
3838
otp: '26'
3939
- elixir: '1.17'
4040
otp: '27'
41+
- elixir: '1.18'
42+
otp: '27'
4143
steps:
4244
- uses: actions/checkout@v4
4345
- uses: erlef/setup-beam@v1

.tool-versions

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
erlang 27.1
2-
elixir 1.17.3-otp-27
1+
erlang 27.2
2+
elixir 1.18.1-otp-27

CHANGELOG.md

+22-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.2.0] - 2025-01-07
11+
12+
### Added
13+
14+
- Added Elixir 1.18.* support to CI.
15+
16+
### Changed
17+
18+
- Refactored tests with new [ExUnit parameterize feature](https://hexdocs.pm/ex_unit/1.18.0/ExUnit.Case.html#module-parameterized-tests).
19+
- `:pool_id` is not required init option anymore. For now it is equal to `worker_module` option value.
20+
21+
### Fixed
22+
23+
- Functions `Poolex.add_idle_workers!/2` and `Poolex.remove_idle_workers!/2` now accept any value of type `GenServer.name()` as their first argument, instead of only `atom()`.
24+
- Supressed Supervisor's error logs in tests.
25+
26+
1027
## [1.1.0] - 2024-12-08
1128

1229
### Added
@@ -15,13 +32,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1532

1633
### Changed
1734

18-
- Monitoring implemetation has been optimized by using plain map instead of `Agent` process.
19-
- Refactored `State` struct by adding list of `@enforced_keys`. ([Details](https://hexdocs.pm/elixir/structs.html#default-values-and-required-keys))
35+
- Monitoring implementation has been optimized by using a plain map instead of the `Agent` process.
36+
- Refactored `State` struct by adding a list of `@enforced_keys`. ([Details](https://hexdocs.pm/elixir/structs.html#default-values-and-required-keys))
2037
- Poolex processes now have higher priority. ([Details](https://www.erlang.org/doc/apps/erts/erlang.html#process_flag_priority))
2138

2239
### Deprecated
2340

24-
- `Poolex.get_state/1` deprecated in favor `:sys.get_state/1`.
41+
- `Poolex.get_state/1` deprecated in favor of `:sys.get_state/1`.
2542

2643
## [1.0.0] - 2024-09-23
2744

@@ -273,7 +290,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
273290
274291
- Supported main interface `Poolex.run/3` with `:timeout` option.
275292
276-
[unreleased]: https://github.com/general-CbIC/poolex/compare/v1.1.0...HEAD
293+
[unreleased]: https://github.com/general-CbIC/poolex/compare/v1.2.0...HEAD
294+
[1.2.0]: https://github.com/general-CbIC/poolex/compare/v1.1.0...v1.2.0
277295
[1.1.0]: https://github.com/general-CbIC/poolex/compare/v1.0.0...v1.1.0
278296
[1.0.0]: https://github.com/general-CbIC/poolex/compare/v0.10.0...v1.0.0
279297
[0.10.0]: https://github.com/general-CbIC/poolex/compare/v0.9.0...v0.10.0

README.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg?style=flat)](https://hexdocs.pm/poolex/)
66
[![License](https://img.shields.io/hexpm/l/poolex.svg?style=flat)](https://github.com/general-CbIC/poolex/blob/main/LICENSE)
77
[![Total Download](https://img.shields.io/hexpm/dt/poolex.svg?style=flat)](https://hex.pm/packages/poolex)
8-
[![Chat on Matrix](https://matrix.to/img/matrix-badge.svg?style=flat)](https://matrix.to/#/#poolex:gitter.im)
98

109
Poolex is a library for managing pools of workers. Inspired by [poolboy](https://github.com/devinus/poolboy).
1110

11+
> [!IMPORTANT]
12+
> Documentation on GitHub corresponds to the current branch. For stable versions' docs see [Hexdocs](https://hexdocs.pm/poolex/).
13+
1214
## Table of Contents
1315

16+
<img alt="Poolex logo" src="https://raw.githubusercontent.com/general-CbIC/poolex/develop/assets/poolex.png" width="250" height="250" align="right"/>
17+
1418
- [Poolex](#poolex)
1519
- [Table of Contents](#table-of-contents)
1620
- [Features](#features)
@@ -59,8 +63,7 @@ In the most typical use of Poolex, you only need to start a pool of workers as a
5963

6064
```elixir
6165
children = [
62-
{Poolex,
63-
pool_id: :worker_pool,
66+
{Poolex,
6467
worker_module: SomeWorker,
6568
workers_count: 5}
6669
]
@@ -71,7 +74,7 @@ Supervisor.start_link(children, strategy: :one_for_one)
7174
Then you can execute any code on the workers with `run/3`:
7275

7376
```elixir
74-
iex> Poolex.run(:worker_pool, &(is_pid?(&1)), checkout_timeout: 1_000)
77+
iex> Poolex.run(SomeWorker, &(is_pid?(&1)), checkout_timeout: 1_000)
7578
{:ok, true}
7679
```
7780

assets/poolex.png

915 KB
Loading

docs/guides/example-of-use.cheatmd

+1-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ defmodule PoolexExample.Application do
3838
def start(_type, _args) do
3939
children = [
4040
{Poolex,
41-
pool_id: :worker_pool,
4241
worker_module: PoolexExample.Worker,
4342
workers_count: 5,
4443
max_overflow: 2}
@@ -66,7 +65,7 @@ defmodule PoolexExample.Test do
6665
defp async_call_square_root(i) do
6766
Task.async(fn ->
6867
Poolex.run(
69-
:worker_pool,
68+
PoolexExample.Worker,
7069
fn pid ->
7170
# Let's wrap the genserver call in a try-catch block. This allows us to trap any exceptions
7271
# that might be thrown and return the worker to Poolex in a clean manner. It also allows

docs/guides/getting-started.cheatmd

+3-6
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
To start a pool you can use either `start/1` or `start_link/1`.
66

77
```elixir
8-
Poolex.start_link(pool_id: :my_pool, worker_module: SomeWorker, workers_count: 10)
8+
Poolex.start_link(worker_module: SomeWorker, workers_count: 10)
99
```
1010

1111
In general, you should place it into your Supervision tree for fault tolerance.
1212

1313
```elixir
1414
children = [
1515
{Poolex,
16-
pool_id: :my_pool,
1716
worker_module: SomeWorker,
1817
workers_count: 10,
1918
max_overflow: 10}
@@ -22,13 +21,11 @@ children = [
2221
Supervisor.start_link(children, strategy: :one_for_one)
2322
```
2423

25-
The second argument should contain a set of options for starting the pool.
26-
2724
## Poolex configuration options
2825

2926
| Option | Description | Example | Default value |
3027
|------------------------|------------------------------------------------------|-----------------------|-------------------------|
31-
| `pool_id` | Identifier by which you will access the pool | `:my_pool` | **option is required** |
28+
| `pool_id` | Identifier by which you will access the pool | `:my_pool` | `worker_module` value |
3229
| `worker_module` | Name of module that implements our worker | `MyApp.Worker` | **option is required** |
3330
| `workers_count` | How many workers should be running in the pool | `5` | **option is required** |
3431
| `max_overflow` | How many workers can be created over the limit | `2` | `0` |
@@ -51,7 +48,7 @@ The third argument contains run options. Currently, there is only one `checkout_
5148

5249
```elixir
5350
iex> Poolex.start_link(pool_id: :agent_pool, worker_module: Agent, worker_args: [fn -> 5 end], workers_count: 1)
54-
iex> Poolex.run(:agent_pool, fn pid -> Agent.get(pid, &(&1)) end)
51+
iex> Poolex.run(:agent_pool, fn pid -> Agent.get(pid, &(&1)) end, checkout_timeout: 5_000)
5552
{:ok, 5}
5653
```
5754

docs/guides/migration-from-poolboy.cheatmd

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def init(_args) do
4343
- max_overflow: 50
4444
- )
4545
+ {Poolex,
46-
+ pool_id: :some_pool,
46+
+ pool_id: {:local, :some_pool},
4747
+ worker_module: MyApp.SomeWorker,
4848
+ workers_count: 100,
4949
+ max_overflow: 50}
@@ -59,12 +59,12 @@ Use `run/3`.
5959
Be careful, unlike `:poolboy.transaction`, `Poolex.run` returns `{:ok, result}`.
6060

6161
```diff
62-
- :poolboy.transaction(
62+
- result = :poolboy.transaction(
6363
- :some_pool,
6464
- fn pid -> some_function(pid) end,
6565
- :timer.seconds(10)
6666
- )
67-
+ Poolex.run(
67+
+ {:ok, result} = Poolex.run(
6868
+ :some_pool,
6969
+ fn pid -> some_function(pid) end,
7070
+ checkout_timeout: :timer.seconds(10)

docs/guides/pool-metrics.cheatmd

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ To enable pool size metrics, you need to set the pool_size_metrics parameter to
1313
```elixir
1414
children = [
1515
{Poolex,
16-
pool_id: :worker_pool,
1716
worker_module: SomeWorker,
1817
workers_count: 5,
1918
pool_size_metrics: true}

examples/poolex_example/lib/poolex_example/application.ex

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ defmodule PoolexExample.Application do
66
def start(_type, _args) do
77
children = [
88
{Poolex,
9-
pool_id: :worker_pool,
109
worker_module: PoolexExample.Worker,
1110
workers_count: 5,
1211
max_overflow: 2,

examples/poolex_example/mix.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%{
2-
"dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"},
3-
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
2+
"dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"},
3+
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
44
"poolex": {:hex, :poolex, "0.4.0", "cc3c5eb921a2ea5886953a2ea3beb0e36148d7d91dd9b628df74c3abb5ea7981", [:mix], [], "hexpm", "0441bf433f8fca4127b68c5985354cb772bba049057bca842f6e73df4f631c17"},
5-
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
6-
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
5+
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
6+
"telemetry_poller": {:hex, :telemetry_poller, "1.1.0", "58fa7c216257291caaf8d05678c8d01bd45f4bdbc1286838a28c4bb62ef32999", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "9eb9d9cbfd81cbd7cdd24682f8711b6e2b691289a0de6826e58452f28c103c8f"},
77
}

lib/poolex.ex

+21-13
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ defmodule Poolex do
3939
@poolex_options_table """
4040
| Option | Description | Example | Default value |
4141
|------------------------|------------------------------------------------------|-----------------------|-----------------------------------|
42-
| `pool_id` | Identifier by which you will access the pool | `:my_pool` | **option is required** |
42+
| `pool_id` | Identifier by which you will access the pool | `:my_pool` | `worker_module` value |
4343
| `worker_module` | Name of module that implements our worker | `MyApp.Worker` | **option is required** |
4444
| `workers_count` | How many workers should be running in the pool | `5` | **option is required** |
4545
| `max_overflow` | How many workers can be created over the limit | `2` | `0` |
@@ -55,7 +55,7 @@ defmodule Poolex do
5555
Any valid GenServer's name. It may be an atom like `:some_pool` or a tuple {:via, Registry, {MyApp.Registry, "pool"}
5656
if you want to use Registry.
5757
"""
58-
@type pool_id() :: GenServer.name()
58+
@type pool_id() :: GenServer.name() | pid()
5959
@typedoc """
6060
#{@poolex_options_table}
6161
"""
@@ -101,8 +101,7 @@ defmodule Poolex do
101101
"""
102102
@spec start(list(poolex_option())) :: GenServer.on_start()
103103
def start(opts) do
104-
pool_id = Keyword.fetch!(opts, :pool_id)
105-
GenServer.start(__MODULE__, opts, name: pool_id, spawn_opt: @spawn_opts)
104+
GenServer.start(__MODULE__, opts, name: get_pool_id(opts), spawn_opt: @spawn_opts)
106105
end
107106

108107
@doc """
@@ -125,8 +124,7 @@ defmodule Poolex do
125124
"""
126125
@spec start_link(list(poolex_option())) :: GenServer.on_start()
127126
def start_link(opts) do
128-
pool_id = Keyword.fetch!(opts, :pool_id)
129-
GenServer.start_link(__MODULE__, opts, name: pool_id, spawn_opt: @spawn_opts)
127+
GenServer.start_link(__MODULE__, opts, name: get_pool_id(opts), spawn_opt: @spawn_opts)
130128
end
131129

132130
@doc """
@@ -139,17 +137,16 @@ defmodule Poolex do
139137
## Examples
140138
141139
children = [
142-
Poolex.child_spec(pool_id: :worker_pool_1, worker_module: SomeWorker, workers_count: 5),
140+
Poolex.child_spec(worker_module: SomeWorker, workers_count: 5),
143141
# or in another way
144-
{Poolex, pool_id: :worker_pool_2, worker_module: SomeOtherWorker, workers_count: 5}
142+
{Poolex, worker_module: SomeOtherWorker, workers_count: 5}
145143
]
146144
147145
Supervisor.start_link(children, strategy: :one_for_one)
148146
"""
149147
@spec child_spec(list(poolex_option())) :: Supervisor.child_spec()
150148
def child_spec(opts) do
151-
pool_id = Keyword.fetch!(opts, :pool_id)
152-
%{id: pool_id, start: {Poolex, :start_link, [opts]}}
149+
%{id: get_pool_id(opts), start: {Poolex, :start_link, [opts]}}
153150
end
154151

155152
@doc """
@@ -252,7 +249,7 @@ defmodule Poolex do
252249
raise ArgumentError, message
253250
end
254251

255-
def add_idle_workers!(pool_id, workers_count) when is_atom(pool_id) and is_integer(workers_count) do
252+
def add_idle_workers!(pool_id, workers_count) when is_integer(workers_count) do
256253
GenServer.call(pool_id, {:add_idle_workers, workers_count})
257254
end
258255

@@ -267,15 +264,15 @@ defmodule Poolex do
267264
raise ArgumentError, message
268265
end
269266

270-
def remove_idle_workers!(pool_id, workers_count) when is_atom(pool_id) and is_integer(workers_count) do
267+
def remove_idle_workers!(pool_id, workers_count) when is_integer(workers_count) do
271268
GenServer.call(pool_id, {:remove_idle_workers, workers_count})
272269
end
273270

274271
@impl GenServer
275272
def init(opts) do
276273
Process.flag(:trap_exit, true)
277274

278-
pool_id = Keyword.fetch!(opts, :pool_id)
275+
pool_id = get_pool_id(opts)
279276
worker_module = Keyword.fetch!(opts, :worker_module)
280277
workers_count = Keyword.fetch!(opts, :workers_count)
281278

@@ -312,6 +309,17 @@ defmodule Poolex do
312309
{:ok, state, {:continue, opts}}
313310
end
314311

312+
@doc """
313+
Returns pool identifier from initialization options.
314+
"""
315+
@spec get_pool_id(list(poolex_option())) :: pool_id()
316+
def get_pool_id(options) do
317+
case Keyword.get(options, :pool_id) do
318+
nil -> Keyword.fetch!(options, :worker_module)
319+
pool_id -> pool_id
320+
end
321+
end
322+
315323
@impl GenServer
316324
def handle_continue(opts, state) do
317325
Metrics.start_poller(opts)

lib/poolex/private/metrics.ex

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ defmodule Poolex.Private.Metrics do
3030
"""
3131
@spec start_poller(list(Poolex.poolex_option())) :: GenServer.on_start()
3232
def start_poller(opts) do
33-
pool_id = Keyword.fetch!(opts, :pool_id)
33+
pool_id = Poolex.get_pool_id(opts)
3434
measurements = collect_measurements(opts)
3535

3636
if measurements == [] do
@@ -46,7 +46,7 @@ defmodule Poolex.Private.Metrics do
4646

4747
@spec collect_measurements(list(Poolex.poolex_option())) :: list()
4848
defp collect_measurements(opts) do
49-
pool_id = Keyword.fetch!(opts, :pool_id)
49+
pool_id = Poolex.get_pool_id(opts)
5050

5151
if Keyword.get(opts, :pool_size_metrics, false) do
5252
[

mix.exs

+6-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ defmodule Poolex.MixProject do
1515
package: package(),
1616
source_url: "https://github.com/general-CbIC/poolex",
1717
start_permanent: Mix.env() == :prod,
18-
version: "1.1.0"
18+
version: "1.2.0"
1919
]
2020
end
2121

@@ -33,7 +33,7 @@ defmodule Poolex.MixProject do
3333
{:telemetry, "~> 1.0"},
3434
{:telemetry_poller, "~> 1.0"},
3535
# Development dependencies
36-
{:credo, "1.7.10", only: [:dev], runtime: false},
36+
{:credo, "1.7.11", only: [:dev], runtime: false},
3737
{:dialyxir, ">= 0.0.0", only: [:dev], runtime: false},
3838
{:doctor, ">= 0.0.0", only: [:dev], runtime: false},
3939
{:ex_check, "~> 0.16.0", only: [:dev], runtime: false},
@@ -45,18 +45,21 @@ defmodule Poolex.MixProject do
4545

4646
defp package do
4747
[
48+
files: ~w(lib mix.exs LICENSE),
4849
licenses: ["MIT"],
4950
links: %{
5051
"Changelog" => "https://github.com/general-CbIC/poolex/blob/develop/CHANGELOG.md",
5152
"GitHub" => "https://github.com/general-CbIC/poolex",
5253
"Sponsor" => "https://github.com/sponsors/general-CbIC"
53-
}
54+
},
55+
maintainers: ["Aleksandr Sysoev"]
5456
]
5557
end
5658

5759
defp docs do
5860
[
5961
main: "readme",
62+
logo: "assets/poolex.png",
6063
extras: [
6164
"README.md",
6265
"docs/guides/getting-started.cheatmd",

0 commit comments

Comments
 (0)