Supervisor.count_children fails when return type is not a list

iex(17)> Supervisor.count_children(:default_pipeline_consumer_supervisor)
** (ArgumentError) argument error
    (stdlib) :maps.from_list(%{active: 0, specs: 1, supervisors: 0, workers: 0})
    (elixir) lib/supervisor.ex:964: Supervisor.count_children/1
iex(17)> :supervisor.count_children(:default_pipeline_consumer_supervisor)
%{active: 0, specs: 1, supervisors: 0, workers: 0}

elixir version: 1.6.6

Does the problem persist on a more recent Elixir version?

Yes.

Interactive Elixir (1.8.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Supervisor.count_children(:default_pipeline_consumer_supervisor)
** (ArgumentError) argument error
    (stdlib) :maps.from_list(%{active: 0, specs: 1, supervisors: 0, workers: 0})
    (elixir) lib/supervisor.ex:953: Supervisor.count_children/1
iex(1)> :supervisor.count_children(:default_pipeline_consumer_supervisor)
%{active: 0, specs: 1, supervisors: 0, workers: 0}

Can you show how you’re creating this supervisor?

defmodule ConsumerSupervisor do
  use ConsumerSupervisor

  # Client API
  def start_link(state \\ %{}) do
    ConsumerSupervisor.start_link(
      __MODULE__,
      state,
      name: :"#{state.name}_consumer_supervisor"
    )
  end

  # Server callbacks
  def init(state) do
    children = [
      worker(Worker, [%{name: state.name}], restart: :temporary)
    ]

    upstream = :"#{state.name}_producer_consumer"

    {
      :ok,
      children,
      strategy: :one_for_one,
      max_restarts: 20,
      max_seconds: 10,
      subscribe_to: [{upstream, [state]}]
    }
  end

  def workers_count(prefix) do
    :supervisor.count_children(process_name(prefix))
    |> Map.get(:workers, 0)
  end
end

This is part of gen_stage pipeline.

You should use https://hexdocs.pm/gen_stage/ConsumerSupervisor.html#count_children/1 then.

3 Likes

Thank you. My bad ignored ConsumerSupervisor documentation.