connection - AMQP 连接丢失不会杀死父进程,因此永远不会发生重新连接
问题描述
我有我的 GenServer 的初始化功能。主管正在照顾它,应该在退出时重新启动它。
def init(_opts) do
username = get_conf(:username)
password = get_conf(:password)
host = get_conf(:host)
port = get_conf(:port)
vhost = String.replace(get_conf(:vhost), "/", "%2f")
{:ok, conn} = Connection.open("amqp://#{username}:#{password}@#{host}:#{port}/#{vhost}")
{:ok, chan} = Channel.open(conn)
state = %State{
exchange: get_conf(:exchange),
channel: chan,
routing_key: get_conf(:routing_key)
}
{:ok, state}
end
当我重新启动 RabbitMQ 时sudo service rabbitmq-server restart
没有建立新的连接。
在调试栏中,我看到以下内容:
当我单击连接 pid <0.417.0> 时,我收到消息说进程不再存在。似乎这个过程已经死了,父母AmqpTransport
对此一无所知。我怎样才能让它AmqpTransport
和它的孩子一起死Connection
?
解决方案
通过添加trapping exits
和链接到Connection
流程来修复它。此外,我在连接期间出现模式匹配错误以避免reached_max_restart_intensity
.
@restart_delay 2000 # 2 seconds
def init(_opts) do
Process.flag(:trap_exit, true)
send(self(), :connect)
{:ok, nil}
end
def handle_info(:connect, state) do
#...
case Connection.open("amqp://#{username}:#{password}@#{host}:#{port}/#{vhost}") do
{:ok, conn} ->
Process.link(conn.pid)
# ...
{:noreply, state}
{:error, :econnrefused} ->
Logger.error("amqp transport failed with connection refused")
Process.send_after(self(), :connect, @restart_delay)
{:noreply, nil}
end
end
def handle_info({:EXIT, pid, reason}, state) do
Logger.error("amqp transport failed with #{inspect(reason)}")
Process.unlink(pid)
Process.send_after(self(), :connect, @restart_delay)
{:noreply, nil}
end
推荐阅读
- java - 在 Android 应用程序中找不到 NullPointerException 的原因
- python - 错误:astype() 有一个意外的关键字参数“类别”
- web-services - 如何将文件从 xamarin 移动应用程序上传到 Web 服务?
- javascript - 回到顶部元素在触摸操作系统上保持悬停状态
- javascript - 按回车时,文本输入值消失(纯js)
- microsoft-graph-api - 用于获取分配给 Azure AD 中特定自定义角色的用户列表的 api
- azure-devops - 用于 gupta 团队开发人员应用程序的 CI/CD 管道?
- salt-stack - salt minions 如何返回多个结果
- laravel - 类 'Ixudra\\Curl\\Facades\\Curl' 未找到
- python - PyQt:从另一个函数访问类之外的函数和自我