Skip to content

Commit acd76b6

Browse files
authored
Fix PartitionSupervisor.count_children/1 and stop/3 to support via tuples (#15161)
The `name()` type for PartitionSupervisor includes `{:via, module(), term()}` tuples, but `count_children/1` and `stop/3` only accepted atoms, raising `FunctionClauseError` for via tuples.
1 parent 6f9afad commit acd76b6

2 files changed

Lines changed: 40 additions & 5 deletions

File tree

lib/elixir/lib/partition_supervisor.ex

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ defmodule PartitionSupervisor do
170170
| {:max_seconds, non_neg_integer()}
171171
| {:with_arguments, (args :: [term()], partition() -> updated_args :: [term()])}
172172

173+
defguardp is_name(name) when is_atom(name) or elem(name, 0) == :via
174+
173175
@doc false
174176
def child_spec(opts) when is_list(opts) do
175177
id =
@@ -366,7 +368,7 @@ defmodule PartitionSupervisor do
366368
"""
367369
@doc since: "1.18.0"
368370
@spec resize!(name(), non_neg_integer()) :: non_neg_integer()
369-
def resize!(name, partitions) when is_integer(partitions) do
371+
def resize!(name, partitions) when is_name(name) and is_integer(partitions) do
370372
supervisor =
371373
GenServer.whereis(name) || exit({:noproc, {__MODULE__, :resize!, [name, partitions]}})
372374

@@ -422,7 +424,7 @@ defmodule PartitionSupervisor do
422424
"""
423425
@doc since: "1.14.0"
424426
@spec partitions(name()) :: non_neg_integer()
425-
def partitions(name) do
427+
def partitions(name) when is_name(name) do
426428
name |> table() |> partitions(name)
427429
end
428430

@@ -470,7 +472,7 @@ defmodule PartitionSupervisor do
470472
# Inlining [module()] | :dynamic here because :supervisor.modules() is not exported
471473
{integer(), pid | :restarting, :worker | :supervisor, [module()] | :dynamic}
472474
]
473-
def which_children(name) when is_atom(name) or elem(name, 0) == :via do
475+
def which_children(name) when is_name(name) do
474476
Supervisor.which_children(name)
475477
end
476478

@@ -498,7 +500,7 @@ defmodule PartitionSupervisor do
498500
supervisors: non_neg_integer,
499501
workers: non_neg_integer
500502
}
501-
def count_children(supervisor) when is_atom(supervisor) do
503+
def count_children(supervisor) when is_name(supervisor) do
502504
Supervisor.count_children(supervisor)
503505
end
504506

@@ -514,7 +516,7 @@ defmodule PartitionSupervisor do
514516
"""
515517
@doc since: "1.14.0"
516518
@spec stop(name(), reason :: term, timeout) :: :ok
517-
def stop(supervisor, reason \\ :normal, timeout \\ :infinity) when is_atom(supervisor) do
519+
def stop(supervisor, reason \\ :normal, timeout \\ :infinity) when is_name(supervisor) do
518520
Supervisor.stop(supervisor, reason, timeout)
519521
end
520522

lib/elixir/test/elixir/partition_supervisor_test.exs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,22 @@ defmodule PartitionSupervisorTest do
147147
assert PartitionSupervisor.stop(config.test) == :ok
148148
assert Process.whereis(config.test) == nil
149149
end
150+
151+
test "with via tuple", config do
152+
{:ok, _} = Registry.start_link(keys: :unique, name: config.test)
153+
154+
name = {:via, Registry, {config.test, :stop_test}}
155+
156+
{:ok, pid} =
157+
PartitionSupervisor.start_link(
158+
child_spec: {Agent, fn -> %{} end},
159+
name: name
160+
)
161+
162+
assert Process.alive?(pid)
163+
assert PartitionSupervisor.stop(name) == :ok
164+
refute Process.alive?(pid)
165+
end
150166
end
151167

152168
describe "partitions/1" do
@@ -272,5 +288,22 @@ defmodule PartitionSupervisorTest do
272288
test "raises noproc for unknown partition supervisor" do
273289
assert {:noproc, _} = catch_exit(PartitionSupervisor.count_children(:unknown))
274290
end
291+
292+
test "with via tuple", config do
293+
{:ok, _} = Registry.start_link(keys: :unique, name: config.test)
294+
295+
name = {:via, Registry, {config.test, :count_test}}
296+
297+
{:ok, _} =
298+
PartitionSupervisor.start_link(
299+
child_spec: {Agent, fn -> %{} end},
300+
name: name
301+
)
302+
303+
partitions = System.schedulers_online()
304+
305+
assert PartitionSupervisor.count_children(name) ==
306+
%{active: partitions, specs: partitions, supervisors: 0, workers: partitions}
307+
end
275308
end
276309
end

0 commit comments

Comments
 (0)