Terminate supervisor after some time

I am wondering if it is possible to terminate a supervisor after some time. For regular GenServer job, I can do something like this if I want process to run for 30 seconds:

use GenServer

# ...

@impl true
def init(state) do
    Process.send_after(self(), :stop, 30_000)
    {:ok, state}
end

@impl true
def handle_info(:stop, state) do
    IO.inspect(state, label: "Stopping")
    {:stop, :normal, state}
end

Is it possible to make supervisor terminate like this after some time? Supervisor does not have handle_info/2. Or is it better to have a GenServer start a supervisor? Sorry I am very new to supervision trees logic. Thank you!

1 Like

You need too call Supervisor.stop from another process to stop the supervisor in a clean way. Now, what are you trying to do exactly?

1 Like

Here’s what I came up with:

defmodule RunForAWhileThenStop do

  use GenServer
  def start_link(state) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end

  @impl true
  def init(opts) do
    time = Keyword.get(opts, :time, 60_000)
    children = [ ... ]

    Process.send_after(self(), :stop, time)
    Supervisor.start_link(children, strategy: :one_for_one)
  end

  @impl true
  def handle_info(:stop, state) do
    {:stop, :normal, state}
  end

This way I can something like RunForAWhileThenStop.start_link(time: 30_000) and let my GenServer run for 30 seconds and then stop.

1 Like

You should have a look at GenServer timeout.

It allows You to stop the server after a certain inactivity period.

Also doing this on a supervisor will kill all children, unless they trap exit.

1 Like

Interesting, I will remember this for the future. In my case, I do want to kill all children processes, so I think it’s ok to stop.