This section correspondsSupervisor (3)Reading in combination, including the details of some supervisory behaviors.
Monitoring Principle
The supervisor is responsible for starting, stopping, and monitoring its sub-processes. The basic idea of the supervisor is that it should keep its sub-processes valid and restart them if necessary.
The child process to be started and monitored is specified by a list of child process specifications. Sub-processes are started in the order in this list and terminated in the reverse order.
Example
Start fromGen_server chapterThe callback module of the server's supervisor can be:
-module(ch_sup).-behaviour(supervisor).-export([start_link/0]).-export([init/1]).start_link() -> supervisor:start_link(ch_sup, []).init(_Args) -> {ok, {{one_for_one, 1, 60}, [{ch3, {ch3, start_link, []}, permanent, brutal_kill, worker, [ch3]}]}}.
one_for_one
Is a restart policy.
1 and 60 define the maximum restart frequency.
Tuples{CH3 ,...}Is the child process specification.
Restart policy one_for_one
If a sub-process is terminated, only the process is restarted.
One_for_all
If a sub-process is terminated, all other sub-processes are terminated, and then all sub-processes are restarted, including the ones that were originally terminated.
Rest_for_one
If a sub-process is terminated, all sub-processes following the terminated process in the startup sequence are terminated. The terminated process and subsequent sub-processes are restarted.
Maximum restart frequency
The supervisor has a built-in mechanism to limit the number of reboots that can occur within a given interval. It consists of two parametersMaxR
AndMaxT
These two parameters are determined by the callback function.init
The returned startup specification.
init(...) -> {ok, {{RestartStrategy, MaxR, MaxT}, [ChildSpec, ...]}}.
IfMaxT
The number of restarts in seconds exceedsMaxR
Then, the supervisor terminates all sub-processes and ends itself.
When the supervisor is terminated, the higher supervisor will take some measures. Either restart the terminated supervisor or stop yourself.
The purpose of this restart mechanism is to prevent a process from repeatedly dying for the same reason and only knowing the situation of repeated restart.
Child Process Specification
{Id, StartFunc, Restart, Shutdown, Type, Modules} Id = term() StartFunc = {M, F, A} M = F = atom() A = [term()] Restart = permanent | transient | temporary Shutdown = brutal_kill | integer() >=0 | infinity Type = worker | supervisor Modules = [Module] | dynamic Module = atom()
Id
Is the name used inside the supervisor to identify the sub-process specification.
StartFunc
Defines difficult book calls for the promoter process. It is a module, function, and parameter tuples, andapply(M, F, A)
Use the same.
Restart
Defines when a terminated sub-process will be restarted:
permanent
Sub-processes will always be restarted.
temporary
Sub-processes will never be restarted.
transient
A child process is restarted only when it is terminated abnormally. That is, the reason for exiting is notnormal
.
Shutdown
Defines how a sub-process should be terminated.
brutal_kill
Indicates that the sub-process should useexit(Child, kill)
To terminate the service unconditionally.
- An integer timeout value indicates that the supervisor calls
exit(Child, shutdown)
Tell the sub-process to terminate and wait for it to return the exit signal. If no exit signal is received in the specified event, useexit(Child, kill)
Terminate sub-processes unconditionally.
- If the sub-process is another governor, set it
infinity
To give the subtree enough time to close.
Type
Whether the sub-process is a supervision or commission process.
Modules
Should be a list with only one element[Module]
, WhereModule
Is the name of the callback module. If the sub-process is a supervisor, gen_server, or gen_fsm. If the sub-process is a gen_eventModules
Should bedynamic
. This information will be used when the processor is released during upgrade and downgrade. SeeRelease Processing.
Example: Start the server in the preceding examplech3
The sub-process specifications of can be:
{ch3, {ch3, start_link, []}, permanent, brutal_kill, worker, [ch3]}
Example: Start fromGen_event BehaviorThe sub-process specifications of the event manager in Chapter 1 can be:
{error_man, {gen_event, start_link, [{local, error_man}]}, permanent, 5000, worker, dynamic}
Both the server and event manager must be a registration process that can be accessed at any time, so they are specifiedpermanent
.
ch3
No cleanup is required before termination, so no close time is required.brutal_kill
That's enough.error_man
It may take some time for the event processor to clean up, soShutdown
Set to 5000 Ms.
Example: Start the sub-process specification of another supervisor:
{sup, {sup, start_link, []}, transient, infinity, supervisor, [sup]}
Start a supervisor
In the preceding example, the supervisor callsch_sup:start_link()
To start:
start_link() -> supervisor:start_link(ch_sup, []).
ch_sup:start_link
Function calledsupervisor:start_link/2
. This function generates a governor program connected to it in parallel.
- First Parameter
ch_sup
Is the name of the callback module, that is, the callback function.init
The module.
- The second parameter, [], will be passed to the callback function
init
. Here,init
This parameter is ignored without any input data.
In this example, the supervisor is not registered. You must use its PID. You can callsupervisor:start_link({local, Name}, Module, Args)
Orsupervisor:start_link({global, Name}, Module, Args)
.
New governor calls callback functionch_sup:init([])
.init
To return{ok, StartSpec}
:
init(_Args) -> {ok, {{one_for_one, 1, 60}, [{ch3, {ch3, start_link, []}, permanent, brutal_kill, worker, [ch3]}]}}.
The supervisor then starts all child processes according to the child process specification in the startup specification. There is only one sub-process --ch3
.
Note that the supervisor: start_link is synchronized. Only when all sub-processes are started will it return.
Add sub-process
In addition to the static supervision tree, we can also dynamically Add sub-processes to an existing supervision process and use the following calls:
supervisor:start_child(Sup, ChildSpec)
Sup
Is the governor PID or name.ChildSpec
Is the child process specification.
Usestart_child/2
The behavior of the added sub-process is basically the same as that of other sub-processes. In addition to this, if the sub-process is dead and rebuilt, all dynamically Added Sub-processes will be lost.
Stop a sub-process
Any sub-process, whether static or dynamic, can be stopped according to the closing rules:
supervisor:terminate_child(Sup, Id)
The sub-process specification corresponding to the stopped sub-process can be deleted using the following call:
supervisor:delete_child(Sup, Id)
Sup
Is the PID or name of the governor.Id
Is the ID specified in the child process specification.
Just like a dynamically added sub-process, the effect of deleting a static sub-process is lost after the supervisor restarts.
Simple_one_for_one Governor
Yessimple_one_for_one
The process of restarting a rule is simplified.one_for_one
All sub-processes are instances of the same process dynamically added.
Example of a callback module of simple_one_for_one statement:
-module(simple_sup).-behaviour(supervisor).-export([start_link/0]).-export([init/1]).start_link() -> supervisor:start_link(simple_sup, []).init(_Args) -> {ok, {{simple_one_for_one, 0, 1}, [{call, {call, start_link, []}, temporary, brutal_kill, worker, [call]}]}}.
After startup, the supervisor does not start any sub-process. All sub-processes are dynamically added by calling the following functions:
supervisor:start_child(Sup, List)
SupIs the PID or name of the governor.List
Is a list of arbitrary values, which will be added to the list of parameters specified in the sub-process specification. If the startup function is specified{M, F, A}
By callingapply(M, F, A++List)
To start.
For examplesimple_sup
Add a sub-process:
supervisor:start_child(Pid, [id1])
Will causeapply(call, start_link, []++[id1])
To start the process, or more directly:
call:start_link(id1)
Stop
Because a supervisor is always part of the supervisor tree, it is terminated by its supervisor. When it is required to shut down, it will stop all sub-processes in the reverse order of startup according to the shutdown specification, and then terminate itself.
5. Supervisor Behavior