【发布时间】:2017-02-17 19:29:55
【问题描述】:
这是我使用 Elixir 的前 2 个小时,所以这可能是一个愚蠢的问题,但我在生成 GenServer 并施放它时遇到了一些问题。我正在使用此模块来监视系统中文件的更改,并且每次在该文件中添加新条目时,我都想将日志投射到生成服务器,该服务器对其进行分析并执行任何应该做的事情关于它的发现。
这是监视更改的模块:
defmodule Test.Watcher do
use ExFSWatch, dirs: ["/var/log/"]
import Test.Receiver, only: [analyze_log: 2]
def callback(file_path, actions) do
if file_path == "/var/log/syslog" do
if :modified in actions do
#~~~~ WHERE DO I GET THIS pid FROM?
analyze_log pid, get_log
end
end
end
def get_log do
{log, _} = System.cmd("tail", ["-n", "1", "/var/log/syslog"])
log
end
end
观察者工作得很好,它接收新的日志,但我遇到了Test.Receiver 的问题,它使用了GenServer。
我的第一个问题是……我在哪里启动这个 gen 服务器? ExFSWatch 有它自己的 start 方法,我无法覆盖它。每次有新日志传入时我是否都会致电start_link(我对此表示怀疑,但我不得不问)?
我读到的所有示例都应该从其他地方开始,获取它的 pid 并将其作为参数传递给 analyze_log 方法,所以,如果我是对的,我唯一剩下的问题是找到找到一个启动 Test.Receiver Genserver 并获取它的 pid 的好地方,这样我就可以在 callback 方法中使用它。
defmodule Test.Receiver do
use GenServer
def start_link do
GenServer.start_link(__MODULE__, :ok, [])
end
def analyze_log(pid, log) do
GenServer.cast(pid, {:analyze_log, log})
end
def init(:ok) do
{:ok, %{}}
end
def handle_cast({:analyze_log, log}, state) do
IO.puts log
{:noreply, state}
end
end
【问题讨论】:
-
大多数具有此类回调接口的模块还有一个额外的“状态”参数来携带此类信息,但由于某种原因,
ExFSWatch似乎没有。除此之外,我能想到的最简单的方法是使用名称生成和注册 Receiver 进程并按名称调用它。 -
我根据您的评论形成了一个答案,因为它有帮助。谢谢。
标签: elixir erlang-otp gen-server