Why Supervisor.start_child dont work

雨燕双飞 提交于 2020-01-14 03:59:11

问题


I'm beginner in Elixir.

I have one application that initiate one custom supervisor in application.ex. Code:

defmodule MyApp do
  use Application

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

    children = [
      supervisor(MyApp.Web.Endpoint, []),
      supervisor(MyApp.Repo, []),

      #my notifier
      MyApp.MyNotifier.Supervisor
    ]
    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

And the code of supervisor is something like this:

defmodule MyApp.MyNotifier.Supervisor do

  use Supervisor

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

  def start_my_notifier(state) do
    Supervisor.start_child(__MODULE__, state)
  end

  def init(:ok) do
    Supervisor.init([], strategy: :one_for_one)
  end

end

And the code of the worker is something like this:

defmodule MyApp.MyNotifier do
  use GenServer

  # Client

  def start_link(state) do
    GenServer.start_link(__MODULE__, state)
  end

  # Server

  def init(state) do
    # Reschedule
    reschedule(state)
    # Reply
    {:ok, state}
  end

  def handle_info(:reschedule, state) do

    case state["count"] < 9 do
      true ->
        # Send notification
        MyNotifier.Helper.notify_past_delivery_time(sate["id"])
        # Reschedule once more
        reschedule(state)
      false ->
        # End process
        Process.exit(self(), :normal)
    end

    {:noreply, state}
  end

  defp reschedule(state) do
    Process.send_after(self(), :reschedule, state["time"] * 60 * 1000)
  end
end

And when something happens in my application i want add/start dynamically one worker with the follow code:

MyNotifier.Supervisor.start_my_notifier(%{"name" => name, "id" => id, "time" => 15, "count" => 0})

When I run my application in debug mode (iex -S mix phx.server) and put one IEx.pry in init function of the worker (then we force the application to go to the state starting the child). Why application never stops?


回答1:


I changed the supervisor strategy for simple_one_for_one in supervisor code.

Supervisor.init([], strategy: :simple_one_for_one)

This works for me.




回答2:


The second parameter of call to Supervisor.start_child/2 should be a child spec, so instead of:

Supervisor.start_child(__MODULE__, state)

it should be somewhat like:

Supervisor.start_child(__MODULE__, [self(), MyApp.MyNotifier, [state]])


来源:https://stackoverflow.com/questions/48705526/why-supervisor-start-child-dont-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!