现在,我们已经成功定义了我们的监督器,它将作为应用程序生命周期的一部分自动启动(和停止)。
但请记住,我们的 KV.Registry 在 handle_cast/2 回调中同时链接(通过 start_link)和监控(通过 monitor)存储容器进程:
链接是双向的,这意味着存储容器崩溃会导致注册表崩溃。虽然我们现在有了监督进程,可以保证注册表恢复正常运行,但注册表崩溃仍然意味着我们会丢失将存储容器名称与其各自进程相关联的所有数据。
换句话说,我们希望即使存储容器崩溃,注册表也能继续运行。让我们编写一个新的注册表测试:
该测试类似于“退出时删除存储容器”,只是我们发送 :shutdown 作为退出原因而不是 :normal,这要更严格一些。如果进程因 :normal 以外的原因终止,则所有链接进程都会收到 EXIT 信号,导致链接进程也终止,除非它正在捕获退出。
由于存储容器终止,注册表也停止了,并且当我们尝试 GenServer.call/3 时我们的测试失败:
1) test removes bucket on crash (KV.RegistryTest)
test/kv/registry_test.exs:26
** (exit) exited in: GenServer.call(#PID<0.148.0>, {:lookup, "shopping"}, 5000)
&n