How can I stop other application in gen_server:terminate/2?

Viewed 118

I'm making my own server with erlang OTP and I stuck in the problem when I use Mnesia.

I start Mnesia in gen_server:init/1 of my worker and stop it in gen_server:terminate/2 of the same worker. Unfortunately, When function mnesia:stop/0 is called by calling application:stop(myApplication) or init:stop(), the application stucks and ends up with this :

=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}]

Of course, this doesn't happen when gen_server:terminate/2 isn't called by setting trap_exit flag as false, but Mnesia also doesn't stop.

I don't know why an application cannot be stopped in other application and want to know it's ok if I don't call mnesia:stop() in the end of my application.

1 Answers

The reason you cannot stop Mnesia when your application is stopping is that at that time the application_controller process is busy with stopping your application. This is a classic deadlock situation when one gen_server (in this case quite indirectly) performs a synchronous call to an other gen_server which in turn wants to do a synchronous call to the first one.

You can break the deadlock by asynchronously shutting down Mnesia after your application stopped. Try calling from your terminate/2 timer:apply_after(0, mnesia, stop, []) for example. (Just spawning a process to do the call is not ideal, it would still belong to your application and would get killed when the application terminates.)

But most of the time you don't really have to bother with stopping Mnesia. Erlang applications by convention leave their dependencies started when stopped. And in case your application is terminated by init:stop(), it will take care of stopping all other applications anyway, including Mnesia.

Related