Reputation: 874
I have a small template project with a single dependency. The behaviour I'm seeking is that when the application is stopped, however it is stopped, its dependencies will be stopped as well and the node will be shut down. In the template project I have a base application called example
and a dependent application called depend
. Each has 3 modules: the application (suffixed _app), the primary supervisor (suffixed _sup) and a basic gen_server (suffixed _srv). depend
is registered in the {applications
entry in example.app
.
According to the Erlang docs:
- If a permanent application terminates, all other applications and the runtime system are also terminated.
Sounds good. That's exactly what I want. I start the application with:
application:ensure_all_started(example, permanent).
This works well enough. I have each callback log its pid, function name and args to the console:
1> application:ensure_all_started(example, permanent).
<0.41.0>: depend_app:start(normal, [])
<0.41.0>: depend_sup:start_link()
<0.42.0>: depend_sup:init([])
<0.42.0>: depend_srv:start_link()
<0.43.0>: depend_srv:init([])
<0.46.0>: example_app:start(normal, [])
<0.46.0>: example_sup:start_link()
<0.47.0>: example_sup:init([])
<0.47.0>: example_srv:start_link()
<0.48.0>: example_srv:init([])
So then I call stop:
1> application:stop(example).
<0.46.0>: example_app:prep_stop([])
<0.48.0>: example_srv:terminate(shutdown, [])
<0.46.0>: example_app:stop([])
ok
2>
=INFO REPORT==== 3-May-2016::08:22:41 ===
application: example
exited: stopped
type: permanent
2>
depend
is not shut down, and it just sits there at the shell. If I force kill the application with erlang:exit/2
, for example, then I get the desired behaviour (aside from the crash dump):
3> erlang:exit(pid(0,46,0), kill).
true
<0.41.0>: depend_app:prep_stop([])
<0.43.0>: depend_srv:terminate(shutdown, [])
<0.41.0>: depend_app:stop([])
4>
=INFO REPORT==== 3-May-2016::09:02:04 ===
application: example
exited: killed
type: permanent
4> {"Kernel pid terminated",application_controller,"{application_terminated,example,killed}"}
Crash dump was written to: erl_crash.dump
Kernel pid terminated (application_controller) ({application_terminated,example,killed})
D:\dev\app_test>
But why not when shutting down normally? It seems to be behaving as a transient
or temporary
application, not as I would expect permanent
based on what's written in the docs.
One additional note, I am version locked to erts-5.10.4/otp-R16B03-1.
Upvotes: 2
Views: 629
Reputation: 8340
Just a bit lower in the same documentation that you cited is written:
An application can always be stopped explicitly by calling
application:stop/1
. Regardless of the mode, no other applications are affected.
You are correct then that it works only when the application is stopped abnormally, e.g. killed. See this code - the first thing OTP does when stopping an application is unlinking the process and deleting info that the application is running. Since a process terminated normally doesn't generate any signals that could be received by other processes, this can lead to a conclusion that the detection if dependent applications should be stopped depends on a link between the application_controller
and the running application.
Upvotes: 3