从另一个应用程序使用 GenServer

Using GenServer from another application

我现在正在努力在我的伞式应用程序的另一个应用程序中使用 GenServer。

结构:
应用程序:

Project_a 和 project_b 都是 --sup 应用程序,我想在 project_b 中使用来自 project_a 的 GenServer。我已将该项目包含在我的 deps.exs 文件中,但我不知道下一步该做什么...

如果我打开观察器,我会在菜单中看到这两个应用程序,但我不断收到错误消息,因为 project_b 无法使用 project_a。

有谁知道我忘记了什么?

我忘记在 project_bmix.exs 文件中添加 project_a

添加as dep是不行的,还必须在de def application部分添加。

参见:https://github.com/josevalim/kv_umbrella 示例。

虽然您对自己问题的回答是正确的,但我可以根据经验告诉您,在另一个应用程序中为您的服务编写适配器是一种很好的做法,旨在将两个应用程序更松散地耦合在一起并避免循环引用.

这是什么意思?获取您要向其发送消息的 GenServer 的 public API 部分,并将其移动到另一个应用程序中的另一个模块。您会发现这与为 HTTP API 编写外观非常相似。 GenServer 的 public API 部分实际上是来自调用进程的 运行 ,即使它在 GenServer 的模块中,所以将它移动到另一个模块就可以了。

请原谅以下代码中的任何语法问题等,因为我正在把它从脑海中拉出来。

改成这样:

defmodule App1.Calculator do
  use GenServer

  def add( num1, num2 ), do: GenServer.call( App1.Caclculator, {:add, num1, num2})

  def handle_call({:add, num1, num2}, _from, state) do
    {:reply, {:ok, num1+num2}, state}
  end
end

收件人:

defmodule App1.Calculator do
  use GenServer

  def handle_call({:add, num1, num2}, _from, state) do
    {:reply, {:ok, num1+num2}, state}
  end
end

defmodule Service.Calculator do
  def add(num1, num2), do: GenServer.call(process_name, {:add, num1, num2})

  # Just an example of how you might have named your node and calculator process
  def process_name, do: {:calculator, :"app1@127.0.0.1"}
end

其中 Service.Caclulator 在名为 Service 的第三个应用程序中,App1App2 可以依赖该应用程序而无需创建循环引用。

为什么必须创建循环引用?一旦您使用 castApp1App2 异步执行操作,那么 App2 将不得不将包含结果的消息发送到 App1,并且没有在第 3 个 Service 应用程序中,您将创建 App1App2 的循环引用。更不用说当您开始发布两个节点(一个用于每个应用程序)时,无需包含所有其他应用程序的编译代码只是为了获得服务的适配器。