Process handle_info:DOWN在被监视的进程死亡后不被调用
我在Process handle_info:DOWN在被监视的进程死亡后不被调用,process,elixir,monitor,Process,Elixir,Monitor,我在进程中遇到问题。监视器/1。我最初的用例是监视凤凰频道,并在它死后进行一些清理。然而,我没有在Phoenix中设置它,而是决定用纯GenServer进行测试 因此,我有一个简单的GenServer,我想跟踪它何时死亡: defmodule Temp.Server do 使用GenServer def start_link(uu),do:GenServer.start_link(uu模块,%{}) def init(args)do 温度监视器监视器(self()) {:好的,args} 结束
进程中遇到问题。监视器/1
。我最初的用例是监视凤凰频道,并在它死后进行一些清理。然而,我没有在Phoenix中设置它,而是决定用纯GenServer进行测试
因此,我有一个简单的GenServer
,我想跟踪它何时死亡:
defmodule Temp.Server do
使用GenServer
def start_link(uu),do:GenServer.start_link(uu模块,%{})
def init(args)do
温度监视器监视器(self())
{:好的,args}
结束
结束
和另一个GenServer,用于监视:
def模块温度监视器do
使用GenServer
需要记录器
def启动链接(u)do
GenServer.start_链接(_模块,[],名称:_模块)
结束
def监视器(pid)do
过程监视器(pid)
结束
def handle_info({:DOWN,ref,:process,{,},state)do
Logger.info(“向下”)
{:诺雷普利州}
结束
结束
因此,如果我理解正确,Process.monitor
将开始监视Temp.Server
进程,并应在服务器
进程死亡时调用句柄信息
匹配:DOWN
。如果我在iex中尝试它:
iex>{uu,pid}=Temp.Server.start\u链接([])
{:好的,#PID}
iex>进程退出(pid,:终止)
真的
我希望从
Monitor
模块调用handle\u info
,并记录“DOWN”,但这不会发生。我做错了什么?我假设它不起作用,因为我从服务器进程调用monitor时,Temp.monitor.monitor(self())
,但我不知道该怎么做。当调用Temp.monitor.monitor/1
方法时,它仍然在Temp.Server
自己的进程中运行,而不是Temp.monitor
。这意味着当Temp.Server
死亡时,:DOWN
消息被发送到Temp.Server
,这是多余的
您要做的是,将服务器进程的pid
传递给Temp.Monitor
,并让它从自己的进程调用process.Monitor
方法,以便它可以监视它。这只能发生在其中一种情况下
您可以通过将实现移动到或:
def模块温度监视器do
使用GenServer
需要记录器
def启动链接(u)do
GenServer.start_链接(_模块,[],名称:_模块)
结束
def监视器(pid)do
cast(_模块,{:monitor,pid})
结束
def handle_cast({:monitor,pid},state)do
过程监视器(pid)
{:诺雷普利州}
结束
def handle_info({:DOWN,ref,:process,{,},state)do
Logger.info(“向下”)
{:诺雷普利州}
结束
结束
它成功了。谢谢现在我明白多了一点。我不认为我在GenServer和回调中定义的API函数会在不同的进程中运行(我想我搞糊涂了,因为它们在同一个模块中,所以我认为它们共享同一个进程或smth)。如果我想同时使用terminate
callback和handle\u info:DOWN
,该怎么办。是否保证在终止回调之后,后一个总是最后调用?我不确定顺序,但无论如何都应该保持逻辑解耦。