Aetherus

Aetherus

Alternative for Supervisor.Spec

I noticed that Spervisor.Spec is deprecated. The question is, what’s the alternative for Supervisor.Spec.worker and Spuervisor.Spec.supervisor that passes 0 or more than 1 arguments to the worker/supervisor module’s start_link?

For example, prior to Elixir 1.5, I can inline the name of an Agent so that I don’t have to define that module:

import Supervisor.Spec

children = [
  worker(Agent, [fn -> [] end, [name: MyAgent]])
]

Supervisor.start_link(children, strategy: :one_for_one)

How can I do this with the new Supervisor API since it requires to pass 2 arguments to Agent.start_link? What if I have a module whose start_link takes no arguments?

Most Liked

gon782

gon782

You can see the new spec stuff here: https://hexdocs.pm/elixir/master/Supervisor.html

To summarize, your alternatives are either the map based specification for each child, which is exactly what an OTP supervisor actually receives behind the curtain, or module based supervisors. The map based child specs were added quite late to OTP which is why the workaround with better UX was added to Elixir:

  %{
    id: Stack,
    start: {Stack, :start_link, [[:hello]]},
    ...
  }

Module based supervisors where you can do:

defmodule MyApp.Supervisor do
  # Automatically defines child_spec/1
  use Supervisor

  def start_link(arg) do
    Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
  end

  def init(_arg) do
    children = [
      {Stack, [:hello]}
    ]

    Supervisor.init(children, strategy: :one_for_one)
  end
end

Note that you can’t start a process by way of start_link/0 with the module based supervisor, because when you pass {Stack, []} or simply Stack it actually will pass [] to start_link. The map based child spec doesn’t have this issue, since you’d just pass start: {Stack, :start_link, []} to it and it’ll work just like every other place where you pass MFAs (Module, Function, Arguments) in Erlang.

gon782

gon782

I think Supervisor is one of those things that gets comparatively little scrutiny and checking up on as time passes in general, being that we can probably count the amount of times we need to sit down and write the specs for them on a couple of hands, if even that, in any given project. I’m guessing most people are used to them just being there.

The docs are generally fantastic, though, so do have a look when therë́s something you’re wondering about.

gon782

gon782

Just as a note, you can use both of the above in the same supervisor:

defmodule Downloader do
  use Application

  def start(_type, _args) do
    config_reader = %{
      id: Downloader.Config.Reader,
      start: {Downloader.Config.Reader, :start_link, []}
    }

    children = [
      Downloader.Download.Supervisor,
      Downloader.RSS.Reader.Supervisor,
      Downloader.Torrent.Filter,
      Downloader.Torrent.Store,
      config_reader,
      Downloader.RSS.Reader.Manager,
      Downloader.Notifier
    ]

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

Where Next?

Popular in Questions Top

Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New

Other popular topics Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement