GenServer `handle_continue` 回调可以直接从另一个进程调用吗?

问题描述 投票:0回答:1

可以通过从同一

handle_continue
内的另一个回调返回
GenServer
来调用
{:noreply, state, {:continue, :foo}
GenServer
回调。

如果我在

GenServer.init
回调之后有一小部分单独的步骤:

defmodule MyGenServer do
  use GenServer

  def start_link(args \\ %{}) do
    GenServer.start_link(__MODULE__, args, [])
  end
  
  @impl true
  def init(args) do
    {:ok, args, {:continue, :foo}}
  end

  @impl true
  def handle_continue(:foo, state)
    case foo(state) do
      {:ok, state} ->
        {:noreply, state, {:continue, :bar}}

      {:error, :bar_not_set} ->
        {:noreply, state}
  end

  @impl true
  def handle_continue(:bar, state)
    state = bar(state)
    {:noreply, state}
  end

  defp foo(state = %{bar: _}) do
    {:ok, state}
  end
  defp foo(_state) do
    {:error, :bar_not_set}
  end

  defp bar(state) do
    # ...
    state
  end
end 
如果

handle_continue(:foo, state)

 包含 
handle_continue(:bar, state)
 键,则按此顺序调用 
args
bar
 回调。如果不是,则永远不会调用 
handle_continue(:bar, state)
 回调。

如果我已经开始

MyGenServer

 例如作为监督树的一部分:

... children = [ ... {MyGenServer, %{foo: "foo"}}, ... ] Supervisor.start_link(children, ...)
是否可以从监督树中的另一个进程触发

MyGenServer.handle_continue(:bar, state)

回调?

这更多的是一个问题,关于是否可以以任何其他方式调用

handle_continue

 回调,而不是在同一个 
GenServer
 内进行回调之后,根本不可能,并且找不到执行 
handle_continue(:bar, state)
 中代码的替代方法。 

erlang elixir gen-server
1个回答
5
投票
无法直接调用回调,但您始终可以:

def handle_cast(:invoke_the_continue, state) do handle_continue(:bar, state) end
然后从服务器外部调用 

GenServer.cast(your_server, :invoke_the_continue)

© www.soinside.com 2019 - 2024. All rights reserved.