我有一个名为Tornado
的模块,它实现了GenServer,我试图将它作为一个名称与模块名称不同的进程产生。
根据{{3}},可以通过给出一个原子作为参数来注册GenServer进程
children = [
worker(Tornado, [[], [name: :tornado_server]])
]
但是当我尝试调用函数时,我收到一个错误:
iex(2)> :tornado_server.send_requests
** (UndefinedFunctionError) undefined function :tornado_server.send_requests/1 (module :tornado_server is not available)
我还尝试将:tornado_server
更改为TornadoServer
** (UndefinedFunctionError) undefined function TornadoServer.send_requests/1 (module TornadoServer is not available)
修改
这是Tornado模块
defmodule Tornado do
use GenServer
# Public API
def start_link(state, opts \\ []) do
GenServer.start_link __MODULE__, state, opts
end
def send_requests(requests) do
GenServer.cast(self, {:send_requests, requests})
end
def get_responses do
GenServer.call(self, :get_responses )
end
# GenServer API
def init(state) do
# creaza 10 Ci
{ :ok, state }
end
def handle_cast({:send_requests, requests}, state) do
state = state ++ [{requests, "127.0.0.1\n"}]
{:noreply, state }
end
def handle_call(:get_responses, _from, state) do
{:reply, state, state}
end
end
以下是启动它的主管:
defmodule TornadoSupervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__,[])
end
def init([]) do
children = [
worker(Tornado, [[], [name: :tornado_server]])
]
supervise(children, strategy: :one_for_one)
end
end
基本上我想这样称呼它:
> TornadoSupervisor.start_link
> TornadoServer.send_requests some_requests_array
> TornadoServer.get_responses
稍后编辑 显然它是有效的,如果我这样做
> GenServer.cast(TornadoServer, {:send_requests,requests})
> GenServer.call(TornadoServer, :get_responses )
但我发现这种语法太冗长了。
答案 0 :(得分:3)
使用:tornado_server.send_requests
调用您的函数将查找不太可能的erlang模块tornado_server
。
您仍需要调用模块上的函数,使用该名称代替pid,而不是模块名称。
如果没有看到您的模块,很难进一步建议。我建议您阅读http://elixir-lang.org/getting-started/mix-otp/genserver.html然后http://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html来查看命名流程的工作原理。
修改强>
GenServer.cast/call
期望pid(或注册名称)作为第一个参数。您正在使用的pid(self
的结果)是调用者,而不是正在运行的GenServer。
您应该存储pid并执行以下操作:
{:ok, pid} = Tornado.start_link()
Tornado.send_requests(pid, some_requests_array)
Tornado.get_responses(pid)
或者您应该替换您的实现以使用提供的名称:
def send_requests(requests) do
GenServer.cast(:tornado_server, {:send_requests, requests})
end
def get_responses do
GenServer.call(:tornado_server, :get_responses )
end
不清楚为什么你不想使用模块名称。对于GenSever来说,这是一个非常常见的约定,你只需要1个。