【问题标题】:Getting message queue from another process in Elixir从 Elixir 中的另一个进程获取消息队列
【发布时间】:2018-03-23 21:19:09
【问题描述】:

我正在尝试将消息队列从一个进程转移到另一个进程。它的工作原理是这样的:第一个进程(GenServer)启动,它根据请求启动第二个进程。然后我在第一个过程中进行转换,这个转换确实调用了第二个过程。在调用第二个进程 I' 之前,尝试获取它的消息队列并始终得到一个空队列。

defmodule First do
use GenServer

def start_link() do
    GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
end

def init(state) do
    {:ok, Map.put(state, :process_list, [])}
end

def handle_call({:start_second, name}, _from, state) do

    process_list = Map.get(state, :process_list)
    {:ok, pid} = SecondProcess.start(name)
    {:ok, Map.put(state, :process_list, [{name, pid}|process_list])}

    {:reply, reply, state1}
end
def handle_call(_msg, _from, state) do
    {:reply, :ok, state}
end

def handle_cast({:test, name}, state) do

    process_list = Map.get(state, :process_list)
    {_, pid} = List.keyfind(process_list, name, 0)

    :erlang.process_info(pid, :messages) |> IO.inspect

    SecondProcess.test(pid)

    IO.puts("TEST FINISHED")

    {:noreply, state}
end
def handle_cast(_msg, state) do
    {:noreply, state}
end

def start_second_process(name) do
    GenServer.call(__MODULE__, {:start_second, name})
end

def test(user_name) do
    GenServer.cast(__MODULE__, {:test, user_name})
    IO.puts("TEST STARTED")
end

结束

【问题讨论】:

  • 我不知道你想在这里完成什么,但我确实觉得有必要指出一些反模式:1) GenServers 不应该启动其他进程,把它留给 Supervisors。单一职责原则在 Elixir 中也同样适用。 2) 你可能永远不想使用start,但总是想使用start_link。让进程在没有任何东西得到完成通知的情况下停止,等等,这不是你想要的。如果只是因为链接的进程在 Erlang 观察者应用程序树中显示得更好。

标签: elixir message-queue


【解决方案1】:

向 GenServer 发送调用或强制转换是通过正常的消息传递完成的。因此,您对流程收件箱的呼叫将在流程收件箱中排队。由于队列的先进先出特性,只有在处理完队列中的所有其他消息后,才会处理您的演员表。因此,您只会看到调用 cast 后排队的消息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 2015-01-13
    • 2017-04-17
    • 2012-02-06
    • 1970-01-01
    相关资源
    最近更新 更多