问题描述
我正在使用 erlang OTP 创建自己的服务器,但在使用 Mnesia
时遇到了问题。
我在我的工人的 gen_server:init/1
中启动 Mnesia,并在同一个工人的 gen_server:terminate/2
中停止它。
不幸的是,当通过调用 mnesia:stop/0
或 application:stop(myApplication)
调用函数 init:stop()
时,应用程序卡住并以这样的方式结束:
=SUPERVISOR REPORT==== 23-Jun-2021::16:54:12.048000 ===
supervisor: {local,temp_sup}
errorContext: shutdown_error
reason: killed
offender: [{pid,<0.159.0>},{id,myMnesiaTest_sup},{mfargs,{myMnesiaTest_sup,start_link,[]}},{restart_type,permanent},{shutdown,10000},{child_type,supervisor}]
当然,这不会发生在 gen_server:terminate/2
没有通过将 trap_exit 标志设置为 false 来调用时,但 Mnesia 也不会停止。
我不知道为什么一个应用程序不能在其他应用程序中停止,我想知道如果我在我的应用程序结束时不调用 mnesia:stop()
就可以了。
解决方法
当您的应用程序停止时您无法停止 Mnesia 的原因是当时 git -c http.sslVerify=false clone https://<github_username>:<personal_access_token>@github.com/<path/to/repo>
进程正忙于停止您的应用程序。这是一个典型的死锁情况,当一个 git -c http.sslVerify=false clone https://140.82.121.4/<path/to/repo>
(在这种情况下是间接的)对另一个 http.sslVerify=false
执行同步调用,而后者又想对第一个进行同步调用。
您可以通过在应用程序停止后异步关闭 Mnesia 来打破僵局。例如,尝试从您的 application_controller
gen_server
拨打电话。 (只是生成一个进程来执行调用并不理想,它仍然属于您的应用程序,并且会在应用程序终止时被杀死。)
但大多数情况下,您真的不必费心阻止 Mnesia。按照惯例,Erlang 应用程序会在停止时启动它们的依赖项。如果您的应用程序被 gen_server
终止,它将负责停止所有其他应用程序,包括 Mnesia。