从另一个应用程序使用GenServer

时间:2017-01-21 15:31:23

标签: elixir otp

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

结构:
应用程式:

  • project_a
  • project_b

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

如果我打开观察者,我在菜单中看到了两个应用程序,但我一直收到错误,因为project_b不能使用project_a。

有谁知道我忘了什么?

2 个答案:

答案 0 :(得分:0)

我忘了在project_a的{​​{1}}文件中添加mix.exs

仅将其添加为dep是不够的,但也必须在de project_b部分添加。

请参阅:https://github.com/josevalim/kv_umbrella以获取示例。

答案 1 :(得分:0)

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

这是什么意思?获取要发送消息的GenServer的公共API部分,并将其移动到另一个应用程序中的另一个模块。您会发现这与为HTTP API编写外观非常相似。 GenServer的公共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的名为App1的第3个应用中,App2cast可以依赖该应用而不创建循环引用。

为什么你可能要创建一个循环引用?只要您使用App1 App2中的App2异步执行操作,App1就必须向Service发送包含结果的消息,在第3个App1应用程序中,您将创建App2和{{1}}的循环引用。更何况当你开始发布两个节点(每个应用程序一个)时,不需要包含整个其他应用程序编译代码只是为了获得服务的适配器。