Terminate supervisor once all workers are done

Hello,

I have a supervision tree, where Application starts -> DynamicSupervisor -> Supervisor -> GenServer (worker).

Once the worker is done with it’s work, it looks like Supervisor still keeps running. Is there a way to stop/terminate the supervisor when it’s workers are done (even under normal exit).

Since the Supervisor keep running and not even reused, I think the app is leaking resource.

Thanks.

Why have the additional Supervisor there in the first place?

I am following the example from chapter 2 of Concurrent Data Processing in Elixir: Fast, Resilient Applications with OTP, GenStage, Flow, and Broadway by Svilen Gospodinov and the source code of this is here - concurrent_elixir/jobber at master · imeraj/concurrent_elixir · GitHub

The way it’s presented, it’s supposed to have multiple supervisor -> worker tree under top level DynamicSupervisor. In case, any of the jobs is terminated abnormally with exception, other supervisors or their jobs should not be impacted.

So instead of this supervision tree -

we got this -

tagging @svilen here too!

Sounds like you want to familiarize with the max_restarts, max_seconds setting. Because you don’t need that indirection to have that behaviour.

1 Like

Thanks for the pointer. I looked into it more and this did the trick -

@impl Supervisor
  def init(args) do
    children = [
      %{
        id: Jobber.Job,
        start: {Jobber.Job, :start_link, [args]},
        significant: true,
        restart: :transient
      }
    ]
    options = [strategy: :one_for_one, max_seconds: 30, auto_shutdown: :all_significant]
    Supervisor.init(children, options)
  end

Looks like auto_shutdown option does it. Not sure if its the ideal solution!

1 Like