繁体   English   中英

Elixir的GenServer handle_call,handle_info,handle_cast没有被调用

[英]Elixir's GenServer handle_call, handle_info, handle_cast not being invoked

我已经实现了一个简单的Application -> DynamicSupervisor系统,其中该Application在启动时创建单个DynamicSupervisor ,然后DynamicSupervisor发送消息以开始一些工作。 问题在于,实际上没有捕获任何消息(通过GenServer的cast ,Kernel的send )。 尝试GenServer.call()会引发以下错误

DynamicSupervisor.handle_call / 3中没有匹配的功能子句

这是奇怪的,因为我已经实现了(针对该规范)。 我确定DynamicSupervisor模块可以启动,并且在启动时不会退出。

应用模块代码:

defmodule Simulacra.Application do
  use Application

  def start(_type, _args) do
    children = [
      Simulacra.MainSupervisor
    ]

    opts = [strategy: :one_for_one, name: Simulacra.Supervisor]
    {:ok, pid} = Supervisor.start_link(children, opts)
    start_supervisors(Supervisor.which_children(pid))
    {:ok, pid}
  end

  defp start_supervisors([h|_t] = list) when is_list(list) do
    {_, pid, _, _} = h
    start_supervisors(pid)
  end

  defp start_supervisors([]) do
    #noop
    IO.puts "Something"
  end

  defp start_supervisors(pid) do
    GenServer.cast(pid, :start)
    send(pid, :ping)
    GenServer.call(pid, :ping) <-- Throws an error
  end
end

主管代码:

defmodule Simulacra.MainSupervisor do
  @moduledoc false
  use DynamicSupervisor

  def start_link([]) do
    DynamicSupervisor.start_link(__MODULE__, [], name: __MODULE__)
  end

  def init(_noop) do
    DynamicSupervisor.init(strategy: :one_for_one)
  end

  def handle_info(:ping, state) do
    IO.puts "sth"
  end

  def handle_cast(:start, state) do
    # do_something
    {:noreply, state}
  end

  def handle_call(:ping, _from, _x) do
    {:reply, "bing", "bong"}
  end

DynamicSupervisorGenServer行为的自定义实现

它具有的唯一可重写功能是child_spec/1

尽管您的casts被有效地忽略了。 当您投射一条消息或发送一条信息时,当进程无法处理它(甚至它不存在)时,VM只会忽略它。call call/3是同步的,因此发送者希望得到回复,这就是为什么看到它上升。

尝试GenServer.cast pid, :foo ,您将收到:ok回去,因为这些消息不会被承诺传递。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM