Getting the following warning: Supervisor.Spec.supervisor/2 is deprecated

I have these warnings:

    warning: Supervisor.Spec.supervisor/2 is deprecated. Use the new child specifications outlined in the Supervisor module instead
    Found at 2 locations:
      lib/my_app123/application.ex:9: MyApp123.Application.start/2
      lib/my_app123/application.ex:10: MyApp123.Application.start/2

    warning: Supervisor.Spec.worker/2 is deprecated. Use the new child specifications outlined in the Supervisor module instead
    Found at 3 locations:
      lib/my_app123/application.ex:11: MyApp123.Application.start/2
      lib/my_app123/application.ex:12: MyApp123.Application.start/2
      lib/my_app123/application.ex:13: MyApp123.Application.start/2

And here’s my code:

  def start(_type, _args) do
    import Supervisor.Spec

    children = [
      {Phoenix.PubSub, [name: MyApp123.PubSub, adapter: Phoenix.PubSub.PG2]},
      supervisor(MyLib123.Repo, []),
      supervisor(MyApp123Web.Endpoint, []),
      worker(MyLib123.Cache, []),
      worker(MyLib123.SomeWorker, []),
      worker(MyApp123.Initializer, [])
    ]

    opts = [strategy: :one_for_one, name: MyApp123.Supervisor]
    Supervisor.start_link(children, opts)
  end

After having checked out the documentation for Spec, it’s not become more clear for me how I should change the code. How?

1 Like

The https://hexdocs.pm/elixir/Supervisor.Spec.html docs state that it is deprecated. Take a look at the example here for the new way: https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html

As I’ve said

This might help you understand the differences and update your code: https://kobrakai.de/kolumne/child-specs-in-elixir/

3 Likes

I wasn’t trying to be unhelpful, sorry. You said you checked the Spec docs, which only state that it’s deprecated and not how to change it, so that wouldn’t be the right place to look. I therefore provided you with an example of the new way. My thinking was along the lines “replicate the example and change it to fit your purpose”, but @LostKobrakai’s link is probably more useful :slight_smile:

2 Likes

@ojinari when people are trying to help you and you’re not quite sure how their post aims to, it might be better to ask for clarification (such as, “Which part of the docs are you referring to specifically?”) rather than telling them they are being ‘unuseful’ or unhelpful. Generally people will be more inclined to help if they feel you appreciate the time and effort they are putting in to your thread to help you :blush:

3 Likes

I was having the same problem following an old tutorial and, as far as I could understand, is a simple new form of syntax.

So it will be like this

    children = [
      %{
       id: MyLib123.Repo,
       start: {MyLib123.Repo, :start_link,  []}
       }
      %{
        id: MyLib123.Cache,
        start: { MyLib123.Cache, :start_link, []}
       }
    ]

    Supervisor.start_link(children, strategy: :one_for_one)

You can see my refactoring at my github in this example supervisor usage code

FWIW, this is going to have a slightly different effect than the old supervisor function - that sets shutdown to :infinity because supervisors are responsible for waiting for all of their children to shut down.

You could address this in several ways, based on the docs:

  def init(_) do
    children = [
      {ElhexDelivery.PostalCode.Supervisor, []}
    ]
  ...

I understood the difference, of using the shutdown: and type:. But when I tried to use the shorthand version in my primer supervisor. The code breaks and returns.

function ElhexDelivery.PostalCode.Supervisor.start_link/1 is undefined or private

By the doc should work, but I didn’t understand what I have to change in this call to make that keep working.

The child_spec function generated by use Supervisor expects a single argument that’s forwarded along to the module’s start_link/1 function - your ElhexDelivery.PostalCode.Supervisor only defines a start_link/0 so you get the “undefined or private” error.

2 Likes

Thanks. Does that really work, and is less code to implement I will let both ways on my example repo for future reference.

I think in most cases @al2o3cr 's suggestion of using the default generated child_spec/1 and start_link/1 functions are not only less code to write, but also less error prone and more idiomatic in Elixir. Even if you do have to customize your child spec there are other ways to go about it than writing the map out by hand.

1 Like