Adding a new worker to the app supervisor dynamically?

When you have a app that starts the toplevel app supervisor, is there a way to add new workers to it dynamically (while app is running).

This is to avoid having to start/stop the app.

Yes You can.

https://hexdocs.pm/elixir/DynamicSupervisor.html

1 Like

Seems like this works? But will it hold up?

defmodule Application do
  use Application

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

    supervisor = Supervisor.start_link(
      [{DynamicSupervisor, strategy: :one_for_one, name: Supervisor}], 
      strategy: :one_for_one)
    {:ok, _} = DynamicSupervisor.start_child(Supervisor, %{id: QLockTest, start: {QLock, :start_link, [[0], QLockTest]}})
    {:ok, _} = DynamicSupervisor.start_child(Supervisor, %{id: QLockTest2, start: {QLock, :start_link, [[0], QLockTest2]}})

    supervisor
  end
end

I think this is what you need https://github.com/slashdotdash/til/blob/master/elixir/dynamic-supervisor-start-children.md

1 Like

Im wondering if the code I pasted is the same effect, it seems to work in a quick test.

But I am guessing the children wont survive the app_down/up?

Carrying it out into its own module solves that?

It is not clear what your use case is…

Dynamic Supervisor should have a module, and be placed in the supervision tree for a start/stop on demand workers.

And to survive the app down/up You would need to know how… maybe retrieve data from db?!

The usecase is to replace the main application supervisor with a dynamicsupervisor (or similar) to achieve the effect of being able to add workers to it on demand without having to restart the app.

You don’t need to overwrite main supervisor for this… just put a dynamic supervisor in it and let it manage start/stop of dynamic worker.

A supervision tree can be very large, and have many nested level, but for sure I would not touch the main Supervisor :slight_smile:

1 Like