Running `mix test` returns warning :simple_one_for_one strategy is deprecated, please use DynamicSupervisor instead

After update Elixir on my machine start to show this msg:

warning: :simple_one_for_one strategy is deprecated, please use DynamicSupervisor instead
(elixir 1.10.3) lib/supervisor.ex:604: Supervisor.init/2
(stdlib 3.13) supervisor.erl:301: :supervisor.init/1
(stdlib 3.13) gen_server.erl:417: :gen_server.init_it/2
(stdlib 3.13) gen_server.erl:385: :gen_server.init_it/6
(stdlib 3.13) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

My machine is:
Erlang/OTP 23 [erts-11.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Elixir 1.10.3 (compiled with Erlang/OTP 21)

My mix.ex :
def project do
[
app: :michi,
version: β€œ3.0.0”,
elixir: β€œ~> 1.10”,
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps(),
dialyzer: [plt_add_deps: :transitive],
default_release: β€œmichi”,
releases: [
michi: [],
demo: []
]
]
end

…

defp deps do
[
{:phoenix, β€œ~> 1.5.3”},
{:phoenix_pubsub, β€œ~> 2.0”},
{:phoenix_ecto, β€œ~> 4.0”},
{:ecto_sql, β€œ~> 3.0”},
{:postgrex, β€œ>= 0.0.0”},
{:gettext, β€œ~> 0.11”},
{:jason, β€œ~> 1.0”},
{:plug_cowboy, β€œ~> 2.1”},
{:guardian, β€œ~> 1.2”},
{:comeonin, β€œ~> 5.0”},
{:cors_plug, β€œ~> 2.0”},
{:bcrypt_elixir, β€œ~> 2.0”},
{:terraform, β€œ~> 1.0.1”},
{:httpoison, β€œ~> 1.5”},
{:poison, β€œ~> 3.1”},
{:ex_aws_s3, β€œ~> 2.0”},
{:ex_aws, β€œ~> 2.0”},
{:hackney, β€œ~> 1.15.2”},
{:sweet_xml, β€œ~> 0.6”},
{:scrivener_ecto, β€œ~> 2.0”},
{:scrivener_list, β€œ~> 2.0”},
{:cloudfront_signer, β€œ~> 0.1.0”},
{:timber, β€œ~> 3.0”},
{:timber_phoenix, β€œ~> 1.0”},
{:timber_plug, β€œ~> 1.0”},
{:bamboo, β€œ~> 1.3”},
{:sans_password, β€œ~> 1.0.0-beta”},
{:prometheus, β€œ~> 4.0”},
{:prometheus_phoenix, β€œ~> 1.3.0”},
{:prometheus_ex, β€œ~> 3.0”},
{:prometheus_ecto, β€œ~> 1.0”},
{:prometheus_plugs, β€œ~> 1.0”},
{:prometheus_process_collector, β€œ~> 1.3”},
{:telemetry, β€œ~> 0.4”},
{:absinthe, β€œ~> 1.5.0”},
{:absinthe_plug, β€œ~> 1.5”},
{:absinthe_relay, β€œ~> 1.5”},
{:dataloader, β€œ~> 1.0.0”},
{:open_graph, β€œ~> 0.0.2”},
{:bodyguard, β€œ~> 2.4”},
{:credo, β€œ~> 1.0.0”, only: [:dev, :test], runtime: false},
{:dialyxir, β€œ~> 1.0.0-rc.6”, only: [:dev], runtime: false},
{:ex_doc, β€œ~> 0.21”, only: [:dev, :test], runtime: false},
{:ex_machina, β€œ~> 2.4”, only: :test},
{:faker, β€œ~> 0.13”, only: :test},
{:ecto_soft_delete, β€œ~> 1.0”}
]
end

1 Like

Hello and welcome,

This warning is true… but did You write some GenServers yourself, with the old syntax? or is it buried inside one of your dependencies… It’s hard to tell.

BTW dialixir is now version 1, not rc anymore. It would be interesting to see what it has to tell.

No GenServers by myself here, and I already sent all my deps. You think could be dialyxir ?
Before I update Phoenix to 1.5 from 1.4, I already had warn about :simple

Well, I mean running…

mix dialyzer

At work, ours come from a few dependencies:

cd deps && rg simple_one_for_one
  • supervisor3 from brod
  • bypass
  • phoenix 1.4.16
  • phoenix_ecto 4.0.0

I’d be thrilled to learn otherwise but AFAIK it’s unavoidable in the combination of Elixir 1.10+ with some older dependencies that aren’t yet revised.

1 Like
Starting Dialyzer
[
  check_plt: false,
  init_plt: '/home/mavmaso/work/michi/_build/dev/dialyxir_erlang-23.0.2_elixir-1.10.3_deps-dev.plt',
  files_rec: ['/home/mavmaso/work/michi/_build/dev/lib/michi/ebin'],
  warnings: [:unknown]
]
Total errors: 12, Skipped: 0, Unnecessary Skips: 0
done in 0m12.0s
:0:unknown_function
Function Repo.get_by/2 does not exist.
________________________________________________________________________________
:0:unknown_function
Function Utils.assoc_ers/1 does not exist.
________________________________________________________________________________
lib/michi/accounts.ex:442:pattern_match
The pattern can never match the type.

Pattern:
_args = %{:valid? => false}

Type:
%{:user_id => _, :valid? => true}
________________________________________________________________________________
lib/michi/content_guards.ex:359:invalid_contract
The @spec for the function does not match the success typing of the function.

Function:
Michi.ContentGuards.mass_create_eac/2

Success typing:
@spec mass_create_eac(%Ecto.Multi{:names => MapSet.t(_), :operations => []}, binary() | integer()) ::
  %Ecto.Multi{
    :names => MapSet.t(_),
    :operations => [{_, {_, _} | {_, _, _} | {_, _, _, _}}, ...]
  }
________________________________________________________________________________
lib/michi/evaluation.ex:74:call_to_missing
Call to missing or private function Michi.Accounts.get_children/1.
________________________________________________________________________________
lib/michi/professional_development/certificate_status.ex:11:no_return
Function changeset/2 has no local return.
________________________________________________________________________________
lib/michi/professional_development/certificate_status.ex:13:call
The function call will not succeed.

Ecto.Changeset.cast(_certificate_status :: any(), [:name], _attrs :: any())

will never return since it differs in arguments with
positions 2nd from the success typing arguments:

(
  {map(), map()}
  | %{:__struct__ => atom() | %{:__changeset__ => map(), _ => _}, atom() => _},
  :invalid | %{:__struct__ => none(), (atom() | binary()) => _},
  [atom() | binary()]
)
________________________________________________________________________________
lib/michi/professional_development/lecture.ex:50:call_to_missing
Call to missing or private function Michi.Utils.maybe_assoc/1.
________________________________________________________________________________
lib/michi_web/controllers/exam_controller.ex:18:call
The function call will not succeed.

MichiWeb.Router.Helpers.exam_path(
  _conn :: %Plug.Conn{
    :adapter => {atom(), _},
    :assigns => %{atom() => _},
    :before_send => [
      (%Plug.Conn{
         :adapter => {_, _},
         :assigns => map(),
         :before_send => [(_ -> any())],
         _ => _
       } ->
         %Plug.Conn{
           :adapter => {_, _},
           :assigns => map(),
           :before_send => [(_ -> any())],
           _ => _
         })
    ],
    :body_params => %Plug.Conn.Unfetched{:aspect => atom(), binary() => _},
    :cookies => %Plug.Conn.Unfetched{:aspect => atom(), binary() => _},
    :halted => boolean(),
    :host => binary(),
    :method => binary(),
    :owner => pid(),
    :params => %Plug.Conn.Unfetched{:aspect => atom(), binary() => _},
    :path_info => [binary()],
    :path_params => %{
      binary() =>
        binary()
        | [binary() | [any()] | %{binary() => _}]
        | %{binary() => binary() | [any()] | %{binary() => _}}
    },
    :port => char(),
    :private => %{atom() => _},
    :query_params => %Plug.Conn.Unfetched{
      :aspect => atom(),
      binary() =>
        binary()
        | [binary() | [any()] | %{binary() => _}]
        | %{binary() => binary() | [any()] | %{binary() => _}}
    },
    :query_string => binary(),
    :remote_ip =>
      {byte(), byte(), byte(), byte()}
      | {char(), char(), char(), char(), char(), char(), char(), char()},
    :req_cookies => %Plug.Conn.Unfetched{:aspect => atom(), binary() => binary()},
    :req_headers => [{binary(), binary()}],
    :request_path => binary(),
    :resp_body =>
      nil
      | binary()
      | maybe_improper_list(
          binary() | maybe_improper_list(any(), binary() | []) | byte(),
          binary() | []
        ),
    :resp_cookies => %{binary() => %{}},
    :resp_headers => [{binary(), binary()}],
    :scheme => :http | :https,
    :script_name => [binary()],
    :secret_key_base => nil | binary(),
    :state => :chunked | :file | :sent | :set | :set_chunked | :set_file | :unset,
    :status => nil | non_neg_integer()
  },
  :show,
  _exam :: %Michi.Evaluation.Exam{_ => _}
)

will never return since it differs in arguments with
positions 2nd from the success typing arguments:

(
  atom() | struct(),
  :add_questions_to_exam | :list_by_group | :update_questions_in_exam,
  any()
)
________________________________________________________________________________
lib/michi_web/controllers/profile_controller.ex:18:call
The function call will not succeed.

MichiWeb.Router.Helpers.profile_path(
  _conn :: %Plug.Conn{
    :adapter => {atom(), _},
    :assigns => %{atom() => _},
    :before_send => [
      (%Plug.Conn{
         :adapter => {_, _},
         :assigns => map(),
         :before_send => [(_ -> any())],
         _ => _
       } ->
         %Plug.Conn{
           :adapter => {_, _},
           :assigns => map(),
           :before_send => [(_ -> any())],
           _ => _
         })
    ],
    :body_params => %Plug.Conn.Unfetched{:aspect => atom(), binary() => _},
    :cookies => %Plug.Conn.Unfetched{:aspect => atom(), binary() => _},
    :halted => boolean(),
    :host => binary(),
    :method => binary(),
    :owner => pid(),
    :params => %Plug.Conn.Unfetched{:aspect => atom(), binary() => _},
    :path_info => [binary()],
    :path_params => %{
      binary() =>
        binary()
        | [binary() | [any()] | %{binary() => _}]
        | %{binary() => binary() | [any()] | %{binary() => _}}
    },
    :port => char(),
    :private => %{atom() => _},
    :query_params => %Plug.Conn.Unfetched{
      :aspect => atom(),
      binary() =>
        binary()
        | [binary() | [any()] | %{binary() => _}]
        | %{binary() => binary() | [any()] | %{binary() => _}}
    },
    :query_string => binary(),
    :remote_ip =>
      {byte(), byte(), byte(), byte()}
      | {char(), char(), char(), char(), char(), char(), char(), char()},
    :req_cookies => %Plug.Conn.Unfetched{:aspect => atom(), binary() => binary()},
    :req_headers => [{binary(), binary()}],
    :request_path => binary(),
    :resp_body =>
      nil
      | binary()
      | maybe_improper_list(
          binary() | maybe_improper_list(any(), binary() | []) | byte(),
          binary() | []
        ),
    :resp_cookies => %{binary() => %{}},
    :resp_headers => [{binary(), binary()}],
    :scheme => :http | :https,
    :script_name => [binary()],
    :secret_key_base => nil | binary(),
    :state => :chunked | :file | :sent | :set | :set_chunked | :set_file | :unset,
    :status => nil | non_neg_integer()
  },
  :show,
  _profile :: %Michi.Accounts.Profile{_ => _}
)

will never return since it differs in arguments with
positions 2nd from the success typing arguments:

(atom() | struct(), :accept_tos | :update, maybe_improper_list() | map())
________________________________________________________________________________
lib/michi_web/controllers/user_essay_answer_controller.ex:33:call
The function call will not succeed.

Plug.Conn.put_status(_conn :: %{:assings => %{:current_user => _, _ => _}, _ => _}, :created)

breaks the contract
(t(), status()) :: t()
________________________________________________________________________________
lib/michi_web/plugs/context.ex:12:call
The function call will not succeed.

Jason.decode!(_current_user :: any(), %{:keys => :atoms})

will never return since the success typing is:
(
  binary()
  | maybe_improper_list(
      binary() | maybe_improper_list(any(), binary() | []) | byte(),
      binary() | []
    ),
  [
    {:keys, :atoms | :atoms! | :copy | :strings | (binary() -> any())}
    | {:strings, :copy | :reference}
  ]
) :: any()

and the contract is
(iodata(), [decode_opt()]) :: term() | no_return()

The :simple_one_for_one comes from supervisors.

After I updated more deps, I finally got away the warn. Thank you guys