DynamiSupervisor not restart child

if child stop, DynamicSupervisor not restart child.

    def add_child(camera) do
        root_dir = "/home/gdeon/page"
        spec = %{
            id: String.to_atom(camera.id),  
            start: {VideoVisor, :start_link, [camera.url, camera.id, root_dir]},
            restart: :permanent,
            type: :worker
        }
        DynamicSupervisor.start_child(__MODULE__, spec)
    end

Hello welcome to the forum, this code looks good, and it does not seem to have error in it. Do You have more info? Like your worker start code?

Just a side note… generating atom dynamically is highly discouraged, because they are limited in size and not garbage collected.

String.to_atom(camera.id)

This is all the code for my dynamic supervisor:

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

@impl true
def init(:ok) do
    DynamicSupervisor.init(strategy: :one_for_one)
end


def add_child(camera) do
    root_dir = "/home/gdeon/vidos"
    spec = %{
        id: String.to_atom(camera.id),  
        start: {VideoVisor, :start_link, [camera.url, camera.id, root_dir]},
        restart: :permanent,
        type: :worker
    }
    DynamicSupervisor.start_child(__MODULE__, spec)
end

And the application runs this dynamic supervisor

I meant the worker, not the supervisor

defmodule Archive.VideoVisor do
    use GenServer, restart: :permanent

    def start_link(camera_url, camera_id, root_dir) do
      GenServer.start(__MODULE__, [camera_url, camera_id, root_dir], name: {:global, "camera:#{camera_id}"})
    end

    def init([camera_url, camera_id, root_dir]) do
      Process.flag(:trap_exit, true)
      ....
      {:ok, initial_state}
    end

    def terminate(_reason, _state) do
      Logger.error("Test")
      :normal
    end

    def handle_info({:EXIT, exit_pid, :normal} = msg, %{ffmpeg_worker: %{pid: worker_pid}} = state) when exit_pid == worker_pid do
      {:stop, :normal, state}
    end

    def handle_info({:EXIT, exit_pid, {:exit_status, 256}} = msg, %{ffmpeg_worker: %{pid: worker_pid}} = state) when exit_pid == worker_pid do
      {:stop, :normal, state}
    end

    def handle_info(msg, state) do
      Logger.warn("Unhandled info for call session... MSG: #{inspect(msg)}, STATE: #{inspect(state)}")
      {:noreply, state}
    end
end

Your code seems ok, it should restart as set as permanent, but it looks your workers have also a supervisor role… they seem to be in charge of some ffmpeg sub workers.

Did You try to comment out code related to sub workers and see if it restarts?

I would choose a solution where ffmpeg_workers have their own supervisor tho.

ffmpeg_worker it
defp spawn_ffmpeg(camera_url, video_dir) do
script_exec = “…”
{:ok, pid, os_pid} = Exexec.run_link(script_exec, stdout: true)
%{pid: pid, os_pid: os_pid}
end

the problem was:
GenServer.start(MODULE, [camera_url, camera_id, root_dir], name: {:global, “camera:#{camera_id}”})
need to
GenServer.start_link(MODULE, [camera_url, camera_id, root_dir], name: {:global, “camera:#{camera_id}”})