Migrating to DynamicSupervisor from Supervisor Elixir

I am trying to upgrade to DynamicSupervisor from Supervisor.

I have this simple supervisor,

  use Supervisor
  alias EvercamMedia.Snapshot.Worker

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

  def init(:ok) do
    children = [worker(Worker, [], restart: :permanent)]
    supervise(children, strategy: :simple_one_for_one, max_restarts: 1_000_000)
  end

  def start_child(settings) do
    Supervisor.start_child(__MODULE__, [settings])
  end

I converted it into this

use DynamicSupervisor
alias EvercamMedia.Snapshot.Worker

def start_link() do
  DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
end

def init(:ok) do
  spec = %{id: Worker, start: {Worker, :start_link, []}}
  DynamicSupervisor.init(spec, strategy: :simple_one_for_one, max_restarts: 1_000_000)
end

def start_child(settings) do
  DynamicSupervisor.start_child(__MODULE__, [settings])
end

But its giving me an error as

    ** (UndefinedFunctionError) function DynamicSupervisor.init/2 is undefined or private
        (elixir 1.10.0) DynamicSupervisor.init(%{id: EvercamMedia.Snapshot.Worker, start: {EvercamMedia.Snapshot.Worker, :start_link, []}}, [strategy: :simple_one_for_one, max_restarts: 1000000])
        (elixir 1.10.0) lib/dynamic_supervisor.ex:541: DynamicSupervisor.init/1

Any help would be thankful, about this issue, Also, I want to know if the above Supervisor implementation make sense ? to have just an ok in init?

I am quiet late to update it, as current logic is not compatible with 1.6x version as well.

DynamicSupervisor is truly dynamic as it no longer expects the spec on init. So you want this:

use DynamicSupervisor
alias EvercamMedia.Snapshot.Worker

def start_link() do
  DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__)
end

def init(:ok) do
  DynamicSupervisor.init(strategy: :one_for_one, max_restarts: 1_000_000)
end

def start_child(settings) do
  spec = %{id: Worker, start: {Worker, :start_link, [settings]}}
  DynamicSupervisor.start_child(__MODULE__, spec)
end

If your Worker implements child specs, then this would work too:

DynamicSupervisor.start_child(__MODULE__, {Worker, settings})
4 Likes