File 4508-Docs-for-supervisor-auto-shutdown.patch of Package erlang

From 39e3e5a5ad81d244ff6b9dc45ac743efb4331cc2 Mon Sep 17 00:00:00 2001
From: Maria-12648430 <maria-12648430@hnc-agency.org>
Date: Tue, 6 Apr 2021 16:56:56 +0200
Subject: [PATCH 08/13] Docs for supervisor auto-shutdown

---
 lib/stdlib/doc/src/supervisor.xml          |  61 ++++++++++++
 system/doc/design_principles/sup_princ.xml | 106 +++++++++++++++++++--
 2 files changed, 157 insertions(+), 10 deletions(-)

diff --git a/lib/stdlib/doc/src/supervisor.xml b/lib/stdlib/doc/src/supervisor.xml
index 352c5c9549..3715c5e7d2 100644
--- a/lib/stdlib/doc/src/supervisor.xml
+++ b/lib/stdlib/doc/src/supervisor.xml
@@ -138,6 +138,47 @@ sup_flags() = #{strategy => strategy(),           % optional
       <c>intensity</c> defaults to <c>1</c> and <c>period</c> defaults to
       <c>5</c>.</p>
 
+    <marker id="auto_shutdown"/>
+    <p>A supervisor can be configured to automatically shut itself down
+      when <seealso marker="#significant_child">significant children</seealso>
+      terminate with the <c>auto_shutdown</c> key in the above map:</p>
+
+    <list type="bulleted">
+      <item>
+        <p><c>never</c> - Automic shutdown is disabled. This is the default
+          setting.</p>
+        <p>With <c>auto_shutdown</c> set to <c>never</c>, child specs
+          with the <c>significant</c> flag set to <c>true</c> are
+          considered invalid and will be rejected.</p>
+      </item>
+      <item>
+        <p><c>any_significant</c> - The supervisor will shut itself down
+          when <em>any</em> significant child terminates, that is, when
+          a <c>transient</c> significant child terminates normally or
+          when a <c> temporary</c> significant child terminates
+          normally or abnormally.</p>
+      </item>
+      <item>
+        <p><c>all_significant</c> - The supervisor will shut itself down
+          when <em>all</em> significant children have terminated, that is,
+          when the <em>last active</em> significant child terminates.
+          The same rules as for <c>any_significant</c> apply.</p>
+      </item>
+    </list>
+
+    <warning>
+      <p>The auto-shutdown feature appeared in OTP 24.0, but
+        applications using this feature will also compile and
+        run with older OTP versions.</p>
+      <p>However, such applications, when compiled with an OTP version
+        that predates the appearance of the auto-shutdown feature,
+        will leak processes because the automatic shutdowns they rely
+        on will not happen.</p>
+      <p>It is up to implementors to take proper precautions if they
+        expect that their applications may be compiled with older OTP
+        versions.</p>
+    </warning>
+
     <marker id="child_spec"/>
     <p>The type definition of a child specification is as follows:</p>
 
@@ -186,6 +227,7 @@ child_spec() = #{id => child_id(),             % mandatory
         <p>The <c>start</c> key is mandatory.</p>
       </item>
       <item>
+        <marker id="restart"/>
         <p><c>restart</c> defines when a terminated child process
           must be restarted. A <c>permanent</c> child process is
           always restarted. A <c>temporary</c> child process is
@@ -198,6 +240,20 @@ child_spec() = #{id => child_id(),             % mandatory
         <p>The <c>restart</c> key is optional. If it is not specified,
           it defaults to <c>permanent</c>.</p>
       </item>
+      <item>
+        <marker id="significant_child"/>
+        <p><c>significant</c> defines if a child is considered significant
+          for <seealso marker="#auto_shutdown">automatic self-shutdown</seealso>
+          of the supervisor.</p>
+        <p>Setting this option to <c>true</c> when the
+          <seealso marker="#restart">restart type</seealso> is <c>permanent</c> is
+          invalid. Also, it is considered invalid to
+          start children with this option set to <c>true</c> in a supervisor
+          when the <seealso marker="#auto_shutdown"><c>auto_shutdown</c></seealso>
+          supervisor flag is set to <c>never</c>.</p>
+        <p>The <c>significant</c> key is optional. If it is not specified,
+          it defaults to <c>false</c>.</p>
+      </item>
       <item>
         <p><c>shutdown</c> defines how a child process must be
           terminated. <c>brutal_kill</c> means that the child process
@@ -339,12 +395,17 @@ child_spec() = #{id => child_id(),             % mandatory
   <funcs>
     <func>
       <name name="check_childspecs" arity="1" since=""/>
+      <name name="check_childspecs" arity="2" since="OTP 24.0"/>
       <fsummary>Check if children specifications are syntactically correct.
       </fsummary>
       <desc>
         <p>Takes a list of child specification as argument
           and returns <c>ok</c> if all of them are syntactically
           correct, otherwise <c>{error,<anno>Error</anno>}</c>.</p>
+        <p>If the optional <c><anno>AutoShutdown</anno></c> argument
+          is given and not <c>undefined</c>, also checks if the child
+          specifications are allowed for the given
+          <seealso marker="#auto_shutdown">auto-shutdown</seealso> option.</p>
       </desc>
     </func>
 
diff --git a/system/doc/design_principles/sup_princ.xml b/system/doc/design_principles/sup_princ.xml
index 60ec23466f..ddac274f12 100644
--- a/system/doc/design_principles/sup_princ.xml
+++ b/system/doc/design_principles/sup_princ.xml
@@ -84,13 +84,17 @@ init(_Args) ->
     <title>Supervisor Flags</title>
     <p>This is the type definition for the supervisor flags:</p>
     <code type="none"><![CDATA[
-sup_flags() = #{strategy => strategy(),         % optional
-                intensity => non_neg_integer(), % optional
-                period => pos_integer()}        % optional
+sup_flags() = #{strategy => strategy(),           % optional
+                intensity => non_neg_integer(),   % optional
+                period => pos_integer(),          % optional
+                auto_shutdown => auto_shutdown()} % optional
     strategy() = one_for_all
                | one_for_one
                | rest_for_one
-               | simple_one_for_one]]></code>
+               | simple_one_for_one
+    auto_shutdown() = never
+                    | any_significant
+                    | all_significant]]></code>
     <list type="bulleted">
       <item>
 	<p><c>strategy</c> specifies
@@ -102,6 +106,11 @@ sup_flags() = #{strategy => strategy(),         % optional
 	  the <seealso marker="#max_intensity">maximum restart
 	  intensity</seealso>.</p>
       </item>
+      <item>
+        <p><c>auto_shutdown</c> specifies if and when a supervisor should
+          <seealso marker="#auto_shutdown">automatically shut itself
+          down</seealso>.</p>
+      </item>
     </list>
   </section>
 
@@ -240,21 +249,86 @@ SupFlags = #{intensity => MaxR, period => MaxT, ...}</code>
     </section>
   </section>
 
+  <section>
+    <marker id="auto_shutdown"></marker>
+    <title>Automatic Shutdown</title>
+    <p>A supervisor can be configured to automatically shut itself down when
+      <seealso marker="#significant_child">significant children</seealso>
+      terminate.</p>
+    <p>Auto-shutdown is specified by the <c>auto_shutdown</c> key in the
+      supervisor flags map returned by the callback function <c>init</c>:</p>
+    <code type="none">
+SupFlags = #{auto_shutdown => AutoShutdown, ...}</code>
+    <p>The <c>auto_shutdown</c> key is optional in this map. If it is not
+      given, it defaults to <c>never</c>.</p>
+    <note>
+      <p>The auto-shutdown facility only applies when significant children
+        terminate by themselves, that is, when their termination was not
+        caused by means of the supervisor. Specifically, neither the
+        termination of a child as a consequence of a sibling's  death in the
+        <c>one_for_all</c> or <c>rest_for_one</c> strategies nor the manual
+        termination of a child by means of <c>supervisor:terminate_child/2</c>
+        will trigger an automatic shutdown.</p>
+    </note>
+
+    <section>
+      <title>never</title>
+      <p>Automatic shutdown is disabled.</p>
+      <p>In this mode, significant children are not accepted. If the
+        child specs returned from <c>init</c> contains significant
+        children, the supervisor will refuse to start. Attempts to
+        start significant children dynamically will be rejected.</p>
+      <p>This is the default setting.</p>
+    </section>
+
+    <section>
+      <title>any_significant</title>
+      <p>The supervisor will automatically shut down itself when
+        <em>any</em> significant child terminates, that is, when a
+        transient significant child terminates normally or when a
+        temporary significant child terminates normally or
+        abnormally.</p>
+    </section>
+
+    <section>
+      <title>all_significant</title>
+      <p>The supervisor will automatically shut down itself when
+        <em>all</em> significant children have terminated, that is,
+        when the <em>last active</em> significant child terminates.
+        The same rules as for <c>any_significant</c> apply.</p>
+    </section>
+
+    <warning>
+      <p>The auto-shutdown feature appeared in OTP 24.0, but
+        applications using this feature will also compile and
+        run with older OTP versions.</p>
+      <p>However, such applications, when compiled with an OTP version
+        that predates the appearance of the auto-shutdown feature,
+        will leak processes because the automatic shutdowns they rely
+        on will not happen.</p>
+      <p>It is up to implementors to take proper precautions if they
+        expect that their applications may be compiled with older OTP
+        versions.</p>
+    </warning>
+  </section>
+
   <section>
     <marker id="spec"></marker>
     <title>Child Specification</title>
     <p>The type definition for a child specification is as follows:</p>
     <code type="none"><![CDATA[
-child_spec() = #{id => child_id(),       % mandatory
-                 start => mfargs(),      % mandatory
-                 restart => restart(),   % optional
-                 shutdown => shutdown(), % optional
-                 type => worker(),       % optional
-                 modules => modules()}   % optional
+child_spec() = #{id => child_id(),             % mandatory
+                 start => mfargs(),            % mandatory
+                 restart => restart(),         % optional
+                 significant => significant(), % optional
+                 shutdown => shutdown(),       % optional
+                 type => worker(),             % optional
+                 modules => modules()}         % optional
     child_id() = term()
     mfargs() = {M :: module(), F :: atom(), A :: [term()]}
     modules() = [module()] | dynamic
     restart() = permanent | transient | temporary
+    significant() = boolean()
     shutdown() = brutal_kill | timeout()
     worker() = worker | supervisor]]></code>
     <list type="bulleted">
@@ -284,6 +358,7 @@ child_spec() = #{id => child_id(),       % mandatory
 	<p>The <c>start</c> key is mandatory.</p>
       </item>
       <item>
+        <marker id="restart"></marker>
         <p><c>restart</c> defines when a terminated child process is to
           be restarted.</p>
         <list type="bulleted">
@@ -299,6 +374,17 @@ child_spec() = #{id => child_id(),       % mandatory
 	<p>The <c>restart</c> key is optional. If it is not given, the
 	  default value <c>permanent</c> will be used.</p>
       </item>
+      <item>
+        <marker id="significant_child"></marker>
+        <p><c>significant</c> defines if a child is considered significant
+          for <seealso marker="#auto_shutdown">automatic
+          self-shutdown</seealso> of the supervisor.</p>
+        <p>It is invalid to set this option to <c>true</c> for a child
+          with <seealso marker="#restart">restart type</seealso>
+          <c>permanent</c> or in a supervisor with
+          <seealso marker="#auto_shutdown">auto-shutdown</seealso>
+          <c>never</c>.</p>
+      </item>
       <item>
         <marker id="shutdown"></marker>
         <p><c>shutdown</c> defines how a child process is to be
-- 
2.26.2

openSUSE Build Service is sponsored by