aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/design_principles
diff options
context:
space:
mode:
Diffstat (limited to 'system/doc/design_principles')
-rw-r--r--system/doc/design_principles/Makefile115
-rw-r--r--system/doc/design_principles/applications.xml378
-rw-r--r--system/doc/design_principles/appup_cookbook.xml627
-rw-r--r--system/doc/design_principles/book.xml42
-rw-r--r--system/doc/design_principles/clientserver.fig40
-rw-r--r--system/doc/design_principles/clientserver.gifbin0 -> 2140 bytes
-rw-r--r--system/doc/design_principles/clientserver.ps199
-rw-r--r--system/doc/design_principles/des_princ.xml285
-rw-r--r--system/doc/design_principles/dist1.fig20
-rw-r--r--system/doc/design_principles/dist1.gifbin0 -> 687 bytes
-rw-r--r--system/doc/design_principles/dist1.ps131
-rw-r--r--system/doc/design_principles/dist2.fig41
-rw-r--r--system/doc/design_principles/dist2.gifbin0 -> 1491 bytes
-rw-r--r--system/doc/design_principles/dist2.ps160
-rw-r--r--system/doc/design_principles/dist3.fig33
-rw-r--r--system/doc/design_principles/dist3.gifbin0 -> 1108 bytes
-rw-r--r--system/doc/design_principles/dist3.ps148
-rw-r--r--system/doc/design_principles/dist4.fig16
-rw-r--r--system/doc/design_principles/dist4.gifbin0 -> 518 bytes
-rw-r--r--system/doc/design_principles/dist4.ps125
-rw-r--r--system/doc/design_principles/dist5.fig40
-rw-r--r--system/doc/design_principles/dist5.gifbin0 -> 1649 bytes
-rw-r--r--system/doc/design_principles/dist5.ps165
-rw-r--r--system/doc/design_principles/distributed_applications.xml217
-rw-r--r--system/doc/design_principles/events.xml221
-rw-r--r--system/doc/design_principles/fsm.xml313
-rw-r--r--system/doc/design_principles/gen_server_concepts.xml269
-rw-r--r--system/doc/design_principles/inclappls.fig33
-rw-r--r--system/doc/design_principles/inclappls.gifbin0 -> 2899 bytes
-rw-r--r--system/doc/design_principles/inclappls.ps808
-rw-r--r--system/doc/design_principles/included_applications.xml150
-rw-r--r--system/doc/design_principles/make.dep31
-rw-r--r--system/doc/design_principles/note.gifbin0 -> 1539 bytes
-rw-r--r--system/doc/design_principles/part.xml43
-rw-r--r--system/doc/design_principles/release_handling.xml667
-rw-r--r--system/doc/design_principles/release_structure.xml302
-rw-r--r--system/doc/design_principles/spec_proc.xml460
-rw-r--r--system/doc/design_principles/sup4.fig32
-rw-r--r--system/doc/design_principles/sup4.gifbin0 -> 1974 bytes
-rw-r--r--system/doc/design_principles/sup4.ps153
-rw-r--r--system/doc/design_principles/sup5.fig43
-rw-r--r--system/doc/design_principles/sup5.gifbin0 -> 2536 bytes
-rw-r--r--system/doc/design_principles/sup5.ps168
-rw-r--r--system/doc/design_principles/sup6.fig46
-rw-r--r--system/doc/design_principles/sup6.gifbin0 -> 1629 bytes
-rw-r--r--system/doc/design_principles/sup6.ps163
-rw-r--r--system/doc/design_principles/sup_princ.xml349
-rw-r--r--system/doc/design_principles/warning.gifbin0 -> 1498 bytes
-rw-r--r--system/doc/design_principles/xmlfiles.mk32
49 files changed, 7065 insertions, 0 deletions
diff --git a/system/doc/design_principles/Makefile b/system/doc/design_principles/Makefile
new file mode 100644
index 0000000000..b3fe136644
--- /dev/null
+++ b/system/doc/design_principles/Makefile
@@ -0,0 +1,115 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include $(ERL_TOP)/erts/vsn.mk
+
+APPLICATION=otp-system-documentation
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/doc/design_principles
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+XML_PART_FILES = part.xml
+
+include xmlfiles.mk
+
+XML_CHAPTER_FILES=$(DESIGN_PRINCIPLES_CHAPTER_FILES)
+
+TOPDOCDIR=..
+
+BOOK_FILES = book.xml
+
+GIF_FILES = \
+ note.gif \
+ clientserver.gif \
+ dist1.gif \
+ dist2.gif \
+ dist3.gif \
+ dist4.gif \
+ dist5.gif \
+ inclappls.gif \
+ sup4.gif \
+ sup5.gif \
+ sup6.gif
+
+XML_FILES = \
+ $(BOOK_FILES) $(XML_CHAPTER_FILES) \
+ $(XML_PART_FILES)
+
+# ----------------------------------------------------
+
+HTML_FILES = \
+ $(XML_PART_FILES:%.xml=%.html)
+
+HTMLDIR = ../html/design_principles
+
+HTML_UG_FILE = $(HTMLDIR)/users_guide.html
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+XML_FLAGS +=
+DVIPS_FLAGS +=
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+$(HTMLDIR)/%.gif: %.gif
+ $(INSTALL_DATA) $< $@
+
+docs: html
+
+local_docs: PDFDIR=../../pdf
+
+html: $(HTML_UG_FILE) gifs
+
+gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
+
+debug opt:
+
+clean clean_docs:
+ rm -rf $(HTMLDIR)
+ rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo)
+ rm -f errs core *~
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_docs_spec: docs
+# $(INSTALL_DIR) $(RELEASE_PATH)/pdf
+# $(INSTALL_DATA) $(TOP_PDF_FILE) $(RELEASE_PATH)/pdf
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(GIF_FILES) $(HTMLDIR)/*.html \
+ $(RELSYSDIR)
+
+
+release_spec:
+
+
diff --git a/system/doc/design_principles/applications.xml b/system/doc/design_principles/applications.xml
new file mode 100644
index 0000000000..121c0179c6
--- /dev/null
+++ b/system/doc/design_principles/applications.xml
@@ -0,0 +1,378 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Applications</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>applications.xml</file>
+ </header>
+ <marker id="appl"></marker>
+ <p>This chapter should be read in conjunction with <c>app(4)</c> and
+ <c>application(3)</c>.</p>
+
+ <section>
+ <title>Application Concept</title>
+ <p>When we have written code implementing some specific
+ functionality, we might want to make the code into an
+ <em>application</em>, that is a component that can be started and
+ stopped as a unit, and which can be re-used in other systems as
+ well.</p>
+ <p>To do this, we create an
+ <seealso marker="#callback_module">application callback module</seealso>, where we describe how the application should
+ be started and stopped.</p>
+ <p>Then, an <em>application specification</em> is needed, which is
+ put in an <seealso marker="#appl_res_file">application resource file</seealso>. Among other things, we specify which
+ modules the application consists of and the name of the callback
+ module.</p>
+ <p>If we use <c>systools</c>, the Erlang/OTP tools for packaging code
+ (see <seealso marker="release_structure">Releases</seealso>),
+ the code for each application is placed in a separate directory
+ following a pre-defined <seealso marker="#app_dir">directory structure</seealso>.</p>
+ </section>
+
+ <section>
+ <marker id="callback_module"></marker>
+ <title>Application Callback Module</title>
+ <p>How to start and stop the code for the application, i.e.
+ the supervision tree, is described by two callback functions:</p>
+ <code type="none">
+start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State}
+stop(State)</code>
+ <p><c>start</c> is called when starting the application and should
+ create the supervision tree by starting the top supervisor.
+ It is expected to return the pid of the top supervisor and an
+ optional term <c>State</c>, which defaults to []. This term is
+ passed as-is to <c>stop</c>.</p>
+ <p><c>StartType</c> is usually the atom <c>normal</c>. It has other
+ values only in the case of a takeover or failover, see
+ <seealso marker="distributed_applications">Distributed Applications</seealso>. <c>StartArgs</c> is defined by the key
+ <c>mod</c> in the <seealso marker="#appl_res_file">application resource file</seealso> file.</p>
+ <p><c>stop/1</c> is called <em>after</em> the application has been
+ stopped and should do any necessary cleaning up. Note that
+ the actual stopping of the application, that is the shutdown of
+ the supervision tree, is handled automatically as described in
+ <seealso marker="#stopping">Starting and Stopping Applications</seealso>.</p>
+ <marker id="ch_app"></marker>
+ <p>Example of an application callback module for packaging
+ the supervision tree from
+ the <seealso marker="sup_princ#ex">Supervisor</seealso> chapter:</p>
+ <code type="none">
+-module(ch_app).
+-behaviour(application).
+
+-export([start/2, stop/1]).
+
+start(_Type, _Args) ->
+ ch_sup:start_link().
+
+stop(_State) ->
+ ok.</code>
+ <p>A library application, which can not be started or stopped,
+ does not need any application callback module.</p>
+ </section>
+
+ <section>
+ <marker id="appl_res_file"></marker>
+ <title>Application Resource File</title>
+ <p>To define an application, we create an <em>application specification</em> which is put in an <em>application resource file</em>, or in short <c>.app</c> file:</p>
+ <code type="none">
+{application, Application, [Opt1,...,OptN]}.</code>
+ <p><c>Application</c>, an atom, is the name of the application.
+ The file must be named <c>Application.app</c>.</p>
+ <p>Each <c>Opt</c> is a tuple <c>{Key, Value}</c> which define a
+ certain property of the application. All keys are optional.
+ Default values are used for any omitted keys.</p>
+ <p>The contents of a minimal <c>.app</c> file for a library
+ application <c>libapp</c> looks like this:</p>
+ <code type="none">
+{application, libapp, []}.</code>
+ <p>The contents of a minimal <c>.app</c> file <c>ch_app.app</c> for
+ a supervision tree application like <c>ch_app</c> looks like this:</p>
+ <code type="none">
+{application, ch_app,
+ [{mod, {ch_app,[]}}]}.</code>
+ <p>The key <c>mod</c> defines the callback module and start
+ argument of the application, in this case <c>ch_app</c> and
+ [], respectively. This means that</p>
+ <code type="none">
+ch_app:start(normal, [])</code>
+ <p>will be called when the application should be started and</p>
+ <code type="none">
+ch_app:stop([])</code>
+ <p>will be called when the application has been stopped.</p>
+ <p>When using <c>systools</c>, the Erlang/OTP tools for packaging
+ code (see <seealso marker="release_structure">Releases</seealso>),
+ the keys <c>description</c>, <c>vsn</c>, <c>modules</c>,
+ <c>registered</c> and <c>applications</c> should also be
+ specified:</p>
+ <code type="none">
+{application, ch_app,
+ [{description, "Channel allocator"},
+ {vsn, "1"},
+ {modules, [ch_app, ch_sup, ch3]},
+ {registered, [ch3]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {ch_app,[]}}
+ ]}.</code>
+ <taglist>
+ <tag><c>description</c></tag>
+ <item>A short description, a string. Defaults to "".</item>
+ <tag><c>vsn</c></tag>
+ <item>Version number, a string. Defaults to "".</item>
+ <tag><c>modules</c></tag>
+ <item>All modules <em>introduced</em> by this application.
+ <c>systools</c> uses this list when generating boot scripts and
+ tar files. A module must be defined in one and only one
+ application. Defaults to [].</item>
+ <tag><c>registered</c></tag>
+ <item>All names of registered processes in the application.
+ <c>systools</c> uses this list to detect name clashes
+ between applications. Defaults to [].</item>
+ <tag><c>applications</c></tag>
+ <item>All applications which must be started before this
+ application is started. <c>systools</c> uses this list to
+ generate correct boot scripts. Defaults to [], but note that
+ all applications have dependencies to at least <c>kernel</c>
+ and <c>stdlib</c>.</item>
+ </taglist>
+ <p>The syntax and contents of of the application resource file
+ are described in detail in <c>app(4)</c>.</p>
+ </section>
+
+ <section>
+ <marker id="app_dir"></marker>
+ <title>Directory Structure</title>
+ <p>When packaging code using <c>systools</c>, the code for each
+ application is placed in a separate directory
+ <c>lib/Application-Vsn</c>, where <c>Vsn</c> is the version number.</p>
+ <p>This may be useful to know, even if <c>systools</c> is not used,
+ since Erlang/OTP itself is packaged according to the OTP principles
+ and thus comes with this directory structure. The code server
+ (see <c>code(3)</c>) will automatically use code from
+ the directory with the highest version number, if there are
+ more than one version of an application present.</p>
+ <p>The application directory structure can of course be used in
+ the development environment as well. The version number may then
+ be omitted from the name.</p>
+ <p>The application directory have the following sub-directories:</p>
+ <list type="bulleted">
+ <item><c>src</c></item>
+ <item><c>ebin</c></item>
+ <item><c>priv</c></item>
+ <item><c>include</c></item>
+ </list>
+ <taglist>
+ <tag><c>src</c></tag>
+ <item>Contains the Erlang source code.</item>
+ <tag><c>ebin</c></tag>
+ <item>Contains the Erlang object code, the <c>beam</c> files.
+ The <c>.app</c> file is also placed here.</item>
+ <tag><c>priv</c></tag>
+ <item>Used for application specific files. For example, C
+ executables are placed here. The function <c>code:priv_dir/1</c>
+ should be used to access this directory.</item>
+ <tag><c>include</c></tag>
+ <item>Used for include files.</item>
+ </taglist>
+ </section>
+
+ <section>
+ <marker id="application_controller"></marker>
+ <title>Application Controller</title>
+ <p>When an Erlang runtime system is started, a number of processes
+ are started as part of the Kernel application. One of these
+ processes is the <em>application controller</em> process,
+ registered as <c>application_controller</c>.</p>
+ <p>All operations on applications are coordinated by the application
+ controller. It is interfaced through the functions in
+ the module <c>application</c>, see <c>application(3)</c>.
+ In particular, applications can be loaded, unloaded, started and
+ stopped.</p>
+ </section>
+
+ <section>
+ <title>Loading and Unloading Applications</title>
+ <p>Before an application can be started, it must be <em>loaded</em>.
+ The application controller reads and stores the information from
+ the <c>.app</c> file.</p>
+ <pre>
+1> <input>application:load(ch_app).</input>
+ok
+2> <input>application:loaded_applications().</input>
+[{kernel,"ERTS CXC 138 10","2.8.1.3"},
+ {stdlib,"ERTS CXC 138 10","1.11.4.3"},
+ {ch_app,"Channel allocator","1"}]</pre>
+ <p>An application that has been stopped, or has never been started,
+ can be unloaded. The information about the application is
+ erased from the internal database of the application controller.</p>
+ <pre>
+3> <input>application:unload(ch_app).</input>
+ok
+4> <input>application:loaded_applications().</input>
+[{kernel,"ERTS CXC 138 10","2.8.1.3"},
+ {stdlib,"ERTS CXC 138 10","1.11.4.3"}]</pre>
+ <note>
+ <p>Loading/unloading an application does not load/unload the code
+ used by the application. Code loading is done the usual way.</p>
+ </note>
+ </section>
+
+ <section>
+ <marker id="stopping"></marker>
+ <title>Starting and Stopping Applications</title>
+ <p>An application is started by calling:</p>
+ <pre>
+5> <input>application:start(ch_app).</input>
+ok
+6> <input>application:which_applications().</input>
+[{kernel,"ERTS CXC 138 10","2.8.1.3"},
+ {stdlib,"ERTS CXC 138 10","1.11.4.3"},
+ {ch_app,"Channel allocator","1"}]</pre>
+ <p>If the application is not already loaded, the application
+ controller will first load it using <c>application:load/1</c>. It
+ will check the value of the <c>applications</c> key, to ensure
+ that all applications that should be started before this
+ application are running.</p>
+ <marker id="application_master"></marker>
+ <p>The application controller then creates an <em>application master</em> for the application. The application master is
+ the group leader of all the processes in the application.
+ The application master starts the application by calling
+ the application callback function <c>start/2</c> in the module,
+ and with the start argument, defined by the <c>mod</c> key in
+ the <c>.app</c> file.</p>
+ <p>An application is stopped, but not unloaded, by calling:</p>
+ <pre>
+7> <input>application:stop(ch_app).</input>
+ok</pre>
+ <p>The application master stops the application by telling the top
+ supervisor to shutdown. The top supervisor tells all its child
+ processes to shutdown etc. and the entire tree is terminated in
+ reversed start order. The application master then calls
+ the application callback function <c>stop/1</c> in the module
+ defined by the <c>mod</c> key.</p>
+ </section>
+
+ <section>
+ <title>Configuring an Application</title>
+ <p>An application can be configured using <em>configuration parameters</em>. These are a list of <c>{Par, Val}</c> tuples
+ specified by a key <c>env</c> in the <c>.app</c> file.</p>
+ <code type="none">
+{application, ch_app,
+ [{description, "Channel allocator"},
+ {vsn, "1"},
+ {modules, [ch_app, ch_sup, ch3]},
+ {registered, [ch3]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {ch_app,[]}},
+ {env, [{file, "/usr/local/log"}]}
+ ]}.</code>
+ <p><c>Par</c> should be an atom, <c>Val</c> is any term.
+ The application can retrieve the value of a configuration
+ parameter by calling <c>application:get_env(App, Par)</c> or a
+ number of similar functions, see <c>application(3)</c>.</p>
+ <p>Example:</p>
+ <pre>
+% <input>erl</input>
+Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
+
+Eshell V5.2.3.6 (abort with ^G)
+1> <input>application:start(ch_app).</input>
+ok
+2> <input>application:get_env(ch_app, file).</input>
+{ok,"/usr/local/log"}</pre>
+ <p>The values in the <c>.app</c> file can be overridden by values
+ in a <em>system configuration file</em>. This is a file which
+ contains configuration parameters for relevant applications:</p>
+ <code type="none">
+[{Application1, [{Par11,Val11},...]},
+ ...,
+ {ApplicationN, [{ParN1,ValN1},...]}].</code>
+ <p>The system configuration should be called <c>Name.config</c> and
+ Erlang should be started with the command line argument
+ <c>-config Name</c>. See <c>config(4)</c> for more information.</p>
+ <p>Example: A file <c>test.config</c> is created with the following
+ contents:</p>
+ <code type="none">
+[{ch_app, [{file, "testlog"}]}].</code>
+ <p>The value of <c>file</c> will override the value of <c>file</c>
+ as defined in the <c>.app</c> file:</p>
+ <pre>
+% <input>erl -config test</input>
+Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
+
+Eshell V5.2.3.6 (abort with ^G)
+1> <input>application:start(ch_app).</input>
+ok
+2> <input>application:get_env(ch_app, file).</input>
+{ok,"testlog"}</pre>
+ <p>If
+ <seealso marker="release_handling#sys">release handling</seealso>
+ is used, exactly one system configuration file should be used and
+ that file should be called <c>sys.config</c></p>
+ <p>The values in the <c>.app</c> file, as well as the values in a
+ system configuration file, can be overridden directly from
+ the command line:</p>
+ <pre>
+% <input>erl -ApplName Par1 Val1 ... ParN ValN</input></pre>
+ <p>Example:</p>
+ <pre>
+% <input>erl -ch_app file '"testlog"'</input>
+Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
+
+Eshell V5.2.3.6 (abort with ^G)
+1> <input>application:start(ch_app).</input>
+ok
+2> <input>application:get_env(ch_app, file).</input>
+{ok,"testlog"}</pre>
+ </section>
+
+ <section>
+ <title>Application Start Types</title>
+ <p>A <em>start type</em> is defined when starting the application:</p>
+ <code type="none">
+application:start(Application, Type)</code>
+ <p><c>application:start(Application)</c> is the same as calling
+ <c>application:start(Application, temporary)</c>. The type can
+ also be <c>permanent</c> or <c>transient</c>:</p>
+ <list type="bulleted">
+ <item>If a permanent application terminates, all other
+ applications and the runtime system are also terminated.</item>
+ <item>If a transient application terminates with reason
+ <c>normal</c>, this is reported but no other applications are
+ terminated. If a transient application terminates abnormally,
+ that is with any other reason than <c>normal</c>, all other
+ applications and the runtime system are also terminated.</item>
+ <item>If a temporary application terminates, this is reported but
+ no other applications are terminated.</item>
+ </list>
+ <p>It is always possible to stop an application explicitly by
+ calling <c>application:stop/1</c>. Regardless of the mode, no
+ other applications will be affected.</p>
+ <p>Note that transient mode is of little practical use, since when
+ a supervision tree terminates, the reason is set to
+ <c>shutdown</c>, not <c>normal</c>.</p>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/appup_cookbook.xml b/system/doc/design_principles/appup_cookbook.xml
new file mode 100644
index 0000000000..bc61578953
--- /dev/null
+++ b/system/doc/design_principles/appup_cookbook.xml
@@ -0,0 +1,627 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Appup Cookbook</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>appup_cookbook.xml</file>
+ </header>
+ <p>This chapter contains examples of <c>.appup</c> files for
+ typical cases of upgrades/downgrades done in run-time.</p>
+
+ <section>
+ <title>Changing a Functional Module</title>
+ <p>When a change has been made to a functional module, for example
+ if a new function has been added or a bug has been corrected,
+ simple code replacement is sufficient.</p>
+ <p>Example:</p>
+ <code type="none">
+{"2",
+ [{"1", [{load_module, m}]}],
+ [{"1", [{load_module, m}]}]
+}.</code>
+ </section>
+
+ <section>
+ <title>Changing a Residence Module</title>
+ <p>In a system implemented according to the OTP Design Principles,
+ all processes, except system processes and special processes,
+ reside in one of the behaviours <c>supervisor</c>,
+ <c>gen_server</c>, <c>gen_fsm</c> or <c>gen_event</c>. These
+ belong to the STDLIB application and upgrading/downgrading
+ normally requires an emulator restart.</p>
+ <p>OTP thus provides no support for changing residence modules
+ except in the case of <seealso marker="#spec">special processes</seealso>.</p>
+ </section>
+
+ <section>
+ <title>Changing a Callback Module</title>
+ <p>A callback module is a functional module, and for code
+ extensions simple code replacement is sufficient.</p>
+ <p>Example: When adding a function to <c>ch3</c> as described in
+ the example in <seealso marker="release_handling#appup">Release Handling</seealso>, <c>ch_app.appup</c> looks as follows:</p>
+ <code type="none">
+{"2",
+ [{"1", [{load_module, ch3}]}],
+ [{"1", [{load_module, ch3}]}]
+}.</code>
+ <p>OTP also supports changing the internal state of behaviour
+ processes, see <seealso marker="#int_state">Changing Internal State</seealso> below.</p>
+ </section>
+
+ <section>
+ <marker id="int_state"></marker>
+ <title>Changing Internal State</title>
+ <p>In this case, simple code replacement is not sufficient.
+ The process must explicitly transform its state using the callback
+ function <c>code_change</c> before switching to the new version
+ of the callback module. Thus synchronized code replacement is
+ used.</p>
+ <p>Example: Consider the gen_server <c>ch3</c> from the chapter
+ about the <seealso marker="gen_server_concepts#ex">gen_server behaviour</seealso>. The internal state is a term <c>Chs</c>
+ representing the available channels. Assume we want add a counter
+ <c>N</c> which keeps track of the number of <c>alloc</c> requests
+ so far. This means we need to change the format to
+ <c>{Chs,N}</c>.</p>
+ <p>The <c>.appup</c> file could look as follows:</p>
+ <code type="none">
+{"2",
+ [{"1", [{update, ch3, {advanced, []}}]}],
+ [{"1", [{update, ch3, {advanced, []}}]}]
+}.</code>
+ <p>The third element of the <c>update</c> instruction is a tuple
+ <c>{advanced,Extra}</c> which says that the affected processes
+ should do a state transformation before loading the new version
+ of the module. This is done by the processes calling the callback
+ function <c>code_change</c> (see <c>gen_server(3)</c>). The term
+ <c>Extra</c>, in this case [], is passed as-is to the function:</p>
+ <marker id="code_change"></marker>
+ <code type="none">
+-module(ch3).
+...
+-export([code_change/3]).
+...
+code_change({down, _Vsn}, {Chs, N}, _Extra) ->
+ {ok, Chs};
+code_change(_Vsn, Chs, _Extra) ->
+ {ok, {Chs, 0}}.</code>
+ <p>The first argument is <c>{down,Vsn}</c> in case of a downgrade,
+ or <c>Vsn</c> in case of an upgrade. The term <c>Vsn</c> is
+ fetched from the 'original' version of the module, i.e.
+ the version we are upgrading from, or downgrading to.</p>
+ <p>The version is defined by the module attribute <c>vsn</c>, if
+ any. There is no such attribute in <c>ch3</c>, so in this case
+ the version is the checksum (a huge integer) of the BEAM file, an
+ uninteresting value which is ignored.</p>
+ <p>(The other callback functions of <c>ch3</c> need to be modified
+ as well and perhaps a new interface function added, this is not
+ shown here).</p>
+ </section>
+
+ <section>
+ <title>Module Dependencies</title>
+ <p>Assume we extend a module by adding a new interface function, as
+ in the example in <seealso marker="release_handling#appup">Release Handling</seealso>, where a function <c>available/0</c> is
+ added to <c>ch3</c>.</p>
+ <p>If we also add a call to this function, say in the module
+ <c>m1</c>, a run-time error could occur during release upgrade if
+ the new version of <c>m1</c> is loaded first and calls
+ <c>ch3:available/0</c> before the new version of <c>ch3</c> is
+ loaded.</p>
+ <p>Thus, <c>ch3</c> must be loaded before <c>m1</c> is, in
+ the upgrade case, and vice versa in the downgrade case. We say
+ that <c>m1</c><em>is dependent on</em><c>ch3</c>. In a release
+ handling instruction, this is expressed by the element
+ <c>DepMods</c>:</p>
+ <code type="none">
+{load_module, Module, DepMods}
+{update, Module, {advanced, Extra}, DepMods}</code>
+ <p><c>DepMods</c> is a list of modules, on which <c>Module</c> is
+ dependent.</p>
+ <p>Example: The module <c>m1</c> in the application <c>myapp</c> is
+ dependent on <c>ch3</c> when upgrading from "1" to "2", or
+ downgrading from "2" to "1":</p>
+ <code type="none">
+myapp.appup:
+
+{"2",
+ [{"1", [{load_module, m1, [ch3]}]}],
+ [{"1", [{load_module, m1, [ch3]}]}]
+}.
+
+ch_app.appup:
+
+{"2",
+ [{"1", [{load_module, ch3}]}],
+ [{"1", [{load_module, ch3}]}]
+}.</code>
+ <p>If <c>m1</c> and <c>ch3</c> had belonged to the same application,
+ the <c>.appup</c> file could have looked like this:</p>
+ <code type="none">
+{"2",
+ [{"1",
+ [{load_module, ch3},
+ {load_module, m1, [ch3]}]}],
+ [{"1",
+ [{load_module, ch3},
+ {load_module, m1, [ch3]}]}]
+}.</code>
+ <p>Note that it is <c>m1</c> that is dependent on <c>ch3</c> also
+ when downgrading. <c>systools</c> knows the difference between
+ up- and downgrading and will generate a correct <c>relup</c>,
+ where <c>ch3</c> is loaded before <c>m1</c> when upgrading but
+ <c>m1</c> is loaded before <c>ch3</c> when downgrading.</p>
+ </section>
+
+ <section>
+ <marker id="spec"></marker>
+ <title>Changing Code For a Special Process</title>
+ <p>In this case, simple code replacement is not sufficient.
+ When a new version of a residence module for a special process
+ is loaded, the process must make a fully qualified call to
+ its loop function to switch to the new code. Thus synchronized
+ code replacement must be used.</p>
+ <note>
+ <p>The name(s) of the user-defined residence module(s) must be
+ listed in the <c>Modules</c> part of the child specification
+ for the special process, in order for the release handler to
+ find the process.</p>
+ </note>
+ <p>Example. Consider the example <c>ch4</c> from the chapter about
+ <seealso marker="spec_proc#ex">sys and proc_lib</seealso>.
+ When started by a supervisor, the child specification could look
+ like this:</p>
+ <code type="none">
+{ch4, {ch4, start_link, []},
+ permanent, brutal_kill, worker, [ch4]}</code>
+ <p>If <c>ch4</c> is part of the application <c>sp_app</c> and a new
+ version of the module should be loaded when upgrading from
+ version "1" to "2" of this application, <c>sp_app.appup</c> could
+ look like this:</p>
+ <code type="none">
+{"2",
+ [{"1", [{update, ch4, {advanced, []}}]}],
+ [{"1", [{update, ch4, {advanced, []}}]}]
+}.</code>
+ <p>The <c>update</c> instruction must contain the tuple
+ <c>{advanced,Extra}</c>. The instruction will make the special
+ process call the callback function <c>system_code_change/4</c>, a
+ function the user must implement. The term <c>Extra</c>, in this
+ case [], is passed as-is to <c>system_code_change/4</c>:</p>
+ <code type="none">
+-module(ch4).
+...
+-export([system_code_change/4]).
+...
+
+system_code_change(Chs, _Module, _OldVsn, _Extra) ->
+ {ok, Chs}.</code>
+ <p>The first argument is the internal state <c>State</c> passed from
+ the function <c>sys:handle_system_msg(Request, From, Parent, Module, Deb, State)</c>, called by the special process when
+ a system message is received. In <c>ch4</c>, the internal state is
+ the set of available channels <c>Chs</c>.</p>
+ <p>The second argument is the name of the module (<c>ch4</c>).</p>
+ <p>The third argument is <c>Vsn</c> or <c>{down,Vsn}</c> as
+ described for
+ <seealso marker="#code_change">gen_server:code_change/3</seealso>.</p>
+ <p>In this case, all arguments but the first are ignored and
+ the function simply returns the internal state again. This is
+ enough if the code only has been extended. If we had wanted to
+ change the internal state (similar to the example in
+ <seealso marker="#int_state">Changing Internal State</seealso>),
+ it would have been done in this function and
+ <c>{ok,Chs2}</c> returned.</p>
+ </section>
+
+ <section>
+ <marker id="sup"></marker>
+ <title>Changing a Supervisor</title>
+ <p>The supervisor behaviour supports changing the internal state,
+ i.e. changing restart strategy and maximum restart frequency
+ properties, as well as changing existing child specifications.</p>
+ <p>Adding and deleting child processes are also possible, but not
+ handled automatically. Instructions must be given by in
+ the <c>.appup</c> file.</p>
+
+ <section>
+ <title>Changing Properties</title>
+ <p>Since the supervisor should change its internal state,
+ synchronized code replacement is required. However,
+ a special <c>update</c> instruction must be used.</p>
+ <p>The new version of the callback module must be loaded first
+ both in the case of upgrade and downgrade. Then the new return
+ value of <c>init/1</c> can be checked and the internal state be
+ changed accordingly.</p>
+ <p>The following <c>upgrade</c> instruction is used for
+ supervisors:</p>
+ <code type="none">
+{update, Module, supervisor}</code>
+ <p>Example: Assume we want to change the restart strategy of
+ <c>ch_sup</c> from the <seealso marker="sup_princ#ex">Supervisor Behaviour</seealso> chapter from one_for_one to one_for_all.
+ We change the callback function <c>init/1</c> in
+ <c>ch_sup.erl</c>:</p>
+ <code type="none">
+-module(ch_sup).
+...
+
+init(_Args) ->
+ {ok, {{one_for_all, 1, 60}, ...}}.</code>
+ <p>The file <c>ch_app.appup</c>:</p>
+ <code type="none">
+{"2",
+ [{"1", [{update, ch_sup, supervisor}]}],
+ [{"1", [{update, ch_sup, supervisor}]}]
+}.</code>
+ </section>
+
+ <section>
+ <title>Changing Child Specifications</title>
+ <p>The instruction, and thus the <c>.appup</c> file, when
+ changing an existing child specification, is the same as when
+ changing properties as described above:</p>
+ <code type="none">
+{"2",
+ [{"1", [{update, ch_sup, supervisor}]}],
+ [{"1", [{update, ch_sup, supervisor}]}]
+}.</code>
+ <p>The changes do not affect existing child processes. For
+ example, changing the start function only specifies how
+ the child process should be restarted, if needed later on.</p>
+ <p>Note that the id of the child specification cannot be changed.</p>
+ <p>Note also that changing the <c>Modules</c> field of the child
+ specification may affect the release handling process itself,
+ as this field is used to identify which processes are affected
+ when doing a synchronized code replacement.</p>
+ </section>
+ <marker id="sup_add"></marker>
+
+ <section>
+ <title>Adding And Deleting Child Processes</title>
+ <p>As stated above, changing child specifications does not affect
+ existing child processes. New child specifications are
+ automatically added, but not deleted. Also, child processes are
+ not automatically started or terminated. Instead, this must be
+ done explicitly using <c>apply</c> instructions.</p>
+ <p>Example: Assume we want to add a new child process <c>m1</c> to
+ <c>ch_sup</c> when upgrading <c>ch_app</c> from "1" to "2".
+ This means <c>m1</c> should be deleted when downgrading from
+ "2" to "1":</p>
+ <code type="none">
+{"2",
+ [{"1",
+ [{update, ch_sup, supervisor},
+ {apply, {supervisor, restart_child, [ch_sup, m1]}}
+ ]}],
+ [{"1",
+ [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
+ {apply, {supervisor, delete_child, [ch_sup, m1]}},
+ {update, ch_sup, supervisor}
+ ]}]
+}.</code>
+ <p>Note that the order of the instructions is important.</p>
+ <p>Note also that the supervisor must be registered as
+ <c>ch_sup</c> for the script to work. If the supervisor is not
+ registered, it cannot be accessed directly from the script.
+ Instead a help function that finds the pid of the supervisor
+ and calls <c>supervisor:restart_child</c> etc. must be written,
+ and it is this function that should be called from the script
+ using the <c>apply</c> instruction.</p>
+ <p>If the module <c>m1</c> is introduced in version "2" of
+ <c>ch_app</c>, it must also be loaded when upgrading and
+ deleted when downgrading:</p>
+ <code type="none">
+{"2",
+ [{"1",
+ [{add_module, m1},
+ {update, ch_sup, supervisor},
+ {apply, {supervisor, restart_child, [ch_sup, m1]}}
+ ]}],
+ [{"1",
+ [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
+ {apply, {supervisor, delete_child, [ch_sup, m1]}},
+ {update, ch_sup, supervisor},
+ {delete_module, m1}
+ ]}]
+}.</code>
+ <p>Note again that the order of the instructions is important.
+ When upgrading, <c>m1</c> must be loaded and the supervisor's
+ child specification changed, before the new child process can
+ be started. When downgrading, the child process must be
+ terminated before child specification is changed and the module
+ is deleted.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Adding or Deleting a Module</title>
+ <p>Example: A new functional module <c>m</c> is added to
+ <c>ch_app</c>:</p>
+ <code type="none">
+{"2",
+ [{"1", [{add_module, m}]}],
+ [{"1", [{delete_module, m}]}]</code>
+ </section>
+
+ <section>
+ <title>Starting or Terminating a Process</title>
+ <p>In a system structured according to the OTP design principles,
+ any process would be a child process belonging to a supervisor,
+ see <seealso marker="#sup_add">Adding and Deleting Child Processes</seealso> above.</p>
+ </section>
+
+ <section>
+ <title>Adding or Removing an Application</title>
+ <p>When adding or removing an application, no <c>.appup</c> file
+ is needed. When generating <c>relup</c>, the <c>.rel</c> files
+ are compared and <c>add_application</c> and
+ <c>remove_application</c> instructions are added automatically.</p>
+ </section>
+
+ <section>
+ <title>Restarting an Application</title>
+ <p>Restarting an application is useful when a change is too
+ complicated to be made without restarting the processes, for
+ example if the supervisor hierarchy has been restructured.</p>
+ <p>Example: When adding a new child <c>m1</c> to <c>ch_sup</c>, as
+ in the <seealso marker="#sup_add">example above</seealso>, an
+ alternative to updating the supervisor is to restart the entire
+ application:</p>
+ <code type="none">
+{"2",
+ [{"1", [{restart_application, ch_app}]}],
+ [{"1", [{restart_application, ch_app}]}]
+}.</code>
+ </section>
+
+ <section>
+ <marker id="app_spec"></marker>
+ <title>Changing an Application Specification</title>
+ <p>When installing a release, the application specifications are
+ automatically updated before evaluating the <c>relup</c> script.
+ Hence, no instructions are needed in the <c>.appup</c> file:</p>
+ <pre>
+{"2",
+ [{"1", []}],
+ [{"1", []}]
+}.</pre>
+ </section>
+
+ <section>
+ <title>Changing Application Configuration</title>
+ <p>Changing an application configuration by updating the <c>env</c>
+ key in the <c>.app</c> file is an instance of changing an
+ application specification, <seealso marker="#app_spec">see above</seealso>.</p>
+ <p>Alternatively, application configuration parameters can be
+ added or updated in <c>sys.config</c>.</p>
+ </section>
+
+ <section>
+ <title>Changing Included Applications</title>
+ <p>The release handling instructions for adding, removing and
+ restarting applications apply to primary applications only.
+ There are no corresponding instructions for included
+ applications. However, since an included application is really a
+ supervision tree with a topmost supervisor, started as a child
+ process to a supervisor in the including application, a
+ <c>relup</c> file can be manually created.</p>
+ <p>Example: Assume we have a release containing an application
+ <c>prim_app</c> which have a supervisor <c>prim_sup</c> in its
+ supervision tree.</p>
+ <p>In a new version of the release, our example application
+ <c>ch_app</c> should be included in <c>prim_app</c>. That is,
+ its topmost supervisor <c>ch_sup</c> should be started as a child
+ process to <c>prim_sup</c>.</p>
+ <p>1) Edit the code for <c>prim_sup</c>:</p>
+ <code type="none">
+init(...) ->
+ {ok, {...supervisor flags...,
+ [...,
+ {ch_sup, {ch_sup,start_link,[]},
+ permanent,infinity,supervisor,[ch_sup]},
+ ...]}}.</code>
+ <p>2) Edit the <c>.app</c> file for <c>prim_app</c>:</p>
+ <code type="none">
+{application, prim_app,
+ [...,
+ {vsn, "2"},
+ ...,
+ {included_applications, [ch_app]},
+ ...
+ ]}.</code>
+ <p>3) Create a new <c>.rel</c> file, including <c>ch_app</c>:</p>
+ <code type="none">
+{release,
+ ...,
+ [...,
+ {prim_app, "2"},
+ {ch_app, "1"}]}.</code>
+
+ <section>
+ <title>Application Restart</title>
+ <p>4a) One way to start the included application is to restart
+ the entire <c>prim_app</c> application. Normally, we would then
+ use the <c>restart_application</c> instruction in
+ the <c>.appup</c> file for <c>prim_app</c>.</p>
+ <p>However, if we did this and then generated a <c>relup</c> file,
+ not only would it contain instructions for restarting (i.e.
+ removing and adding) <c>prim_app</c>, it would also contain
+ instructions for starting <c>ch_app</c> (and stopping it, in
+ the case of downgrade). This is due to the fact that
+ <c>ch_app</c> is included in the new <c>.rel</c> file, but not
+ in the old one.</p>
+ <p>Instead, a correct <c>relup</c> file can be created manually,
+ either from scratch or by editing the generated version.
+ The instructions for starting/stopping <c>ch_app</c> are
+ replaced by instructions for loading/unloading the application:</p>
+ <code type="none">
+{"B",
+ [{"A",
+ [],
+ [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
+ {load_object_code,{prim_app,"2",[prim_app,prim_sup]}},
+ point_of_no_return,
+ {apply,{application,stop,[prim_app]}},
+ {remove,{prim_app,brutal_purge,brutal_purge}},
+ {remove,{prim_sup,brutal_purge,brutal_purge}},
+ {purge,[prim_app,prim_sup]},
+ {load,{prim_app,brutal_purge,brutal_purge}},
+ {load,{prim_sup,brutal_purge,brutal_purge}},
+ {load,{ch_sup,brutal_purge,brutal_purge}},
+ {load,{ch3,brutal_purge,brutal_purge}},
+ {apply,{application,load,[ch_app]}},
+ {apply,{application,start,[prim_app,permanent]}}]}],
+ [{"A",
+ [],
+ [{load_object_code,{prim_app,"1",[prim_app,prim_sup]}},
+ point_of_no_return,
+ {apply,{application,stop,[prim_app]}},
+ {apply,{application,unload,[ch_app]}},
+ {remove,{ch_sup,brutal_purge,brutal_purge}},
+ {remove,{ch3,brutal_purge,brutal_purge}},
+ {purge,[ch_sup,ch3]},
+ {remove,{prim_app,brutal_purge,brutal_purge}},
+ {remove,{prim_sup,brutal_purge,brutal_purge}},
+ {purge,[prim_app,prim_sup]},
+ {load,{prim_app,brutal_purge,brutal_purge}},
+ {load,{prim_sup,brutal_purge,brutal_purge}},
+ {apply,{application,start,[prim_app,permanent]}}]}]
+}.</code>
+ </section>
+
+ <section>
+ <title>Supervisor Change</title>
+ <p>4b) Another way to start the included application (or stop it
+ in the case of downgrade) is by combining instructions for
+ adding and removing child processes to/from <c>prim_sup</c> with
+ instructions for loading/unloading all <c>ch_app</c> code and
+ its application specification.</p>
+ <p>Again, the <c>relup</c> file is created manually. Either from
+ scratch or by editing a generated version. Load all code for
+ <c>ch_app</c> first, and also load the application
+ specification, before <c>prim_sup</c> is updated. When
+ downgrading, <c>prim_sup</c> should be updated first, before
+ the code for <c>ch_app</c> and its application specification
+ are unloaded.</p>
+ <code type="none">
+{"B",
+ [{"A",
+ [],
+ [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
+ {load_object_code,{prim_app,"2",[prim_sup]}},
+ point_of_no_return,
+ {load,{ch_sup,brutal_purge,brutal_purge}},
+ {load,{ch3,brutal_purge,brutal_purge}},
+ {apply,{application,load,[ch_app]}},
+ {suspend,[prim_sup]},
+ {load,{prim_sup,brutal_purge,brutal_purge}},
+ {code_change,up,[{prim_sup,[]}]},
+ {resume,[prim_sup]},
+ {apply,{supervisor,restart_child,[prim_sup,ch_sup]}}]}],
+ [{"A",
+ [],
+ [{load_object_code,{prim_app,"1",[prim_sup]}},
+ point_of_no_return,
+ {apply,{supervisor,terminate_child,[prim_sup,ch_sup]}},
+ {apply,{supervisor,delete_child,[prim_sup,ch_sup]}},
+ {suspend,[prim_sup]},
+ {load,{prim_sup,brutal_purge,brutal_purge}},
+ {code_change,down,[{prim_sup,[]}]},
+ {resume,[prim_sup]},
+ {remove,{ch_sup,brutal_purge,brutal_purge}},
+ {remove,{ch3,brutal_purge,brutal_purge}},
+ {purge,[ch_sup,ch3]},
+ {apply,{application,unload,[ch_app]}}]}]
+}.</code>
+ </section>
+ </section>
+
+ <section>
+ <title>Changing Non-Erlang Code</title>
+ <p>Changing code for a program written in another programming
+ language than Erlang, for example a port program, is very
+ application dependent and OTP provides no special support for it.</p>
+ <p>Example, changing code for a port program: Assume that
+ the Erlang process controlling the port is a gen_server
+ <c>portc</c> and that the port is opened in the callback function
+ <c>init/1</c>:</p>
+ <code type="none">
+init(...) ->
+ ...,
+ PortPrg = filename:join(code:priv_dir(App), "portc"),
+ Port = open_port({spawn,PortPrg}, [...]),
+ ...,
+ {ok, #state{port=Port, ...}}.</code>
+ <p>If the port program should be updated, we can extend the code for
+ the gen_server with a <c>code_change</c> function which closes
+ the old port and opens a new port. (If necessary, the gen_server
+ may first request data that needs to be saved from the port
+ program and pass this data to the new port):</p>
+ <code type="none">
+code_change(_OldVsn, State, port) ->
+ State#state.port ! close,
+ receive
+ {Port,close} ->
+ true
+ end,
+ PortPrg = filename:join(code:priv_dir(App), "portc"),
+ Port = open_port({spawn,PortPrg}, [...]),
+ {ok, #state{port=Port, ...}}.</code>
+ <p>Update the application version number in the <c>.app</c> file
+ and write an <c>.appup</c> file:</p>
+ <code type="none">
+["2",
+ [{"1", [{update, portc, {advanced,port}}]}],
+ [{"1", [{update, portc, {advanced,port}}]}]
+].</code>
+ <p>Make sure the <c>priv</c> directory where the C program is
+ located is included in the new release package:</p>
+ <pre>
+1> <input>systools:make_tar("my_release", [{dirs,[priv]}]).</input>
+...</pre>
+ </section>
+
+ <section>
+ <title>Emulator Restart</title>
+ <p>If the emulator can or should be restarted, the very simple
+ <c>.relup</c> file can be created manually:</p>
+ <code type="none">
+{"B",
+ [{"A",
+ [],
+ [restart_new_emulator]}],
+ [{"A",
+ [],
+ [restart_new_emulator]}]
+}.</code>
+ <p>This way, the release handler framework with automatic packing
+ and unpacking of release packages, automatic path updates etc. can
+ be used without having to specify <c>.appup</c> files.</p>
+ <p>If some transformation of persistent data, for example database
+ contents, needs to be done before installing the new release
+ version, instructions for this can be added to the <c>.relup</c>
+ file as well.</p>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/book.xml b/system/doc/design_principles/book.xml
new file mode 100644
index 0000000000..615722ac12
--- /dev/null
+++ b/system/doc/design_principles/book.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE book SYSTEM "book.dtd">
+
+<book xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header titlestyle="normal">
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>OTP Design Principles</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <insidecover>
+ </insidecover>
+ <pagetext>OTP Design Principles</pagetext>
+ <preamble>
+ <contents level="2"></contents>
+ </preamble>
+ <parts lift="no">
+ <xi:include href="part.xml"/>
+ </parts>
+ <listofterms></listofterms>
+ <index></index>
+</book>
+
diff --git a/system/doc/design_principles/clientserver.fig b/system/doc/design_principles/clientserver.fig
new file mode 100644
index 0000000000..5854169ced
--- /dev/null
+++ b/system/doc/design_principles/clientserver.fig
@@ -0,0 +1,40 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3150 750 404 404 3150 750 3300 1125
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2175 2025 404 404 2175 2025 2325 2400
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1650 3525 404 404 1650 3525 1800 3900
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 5025 2925 404 404 5025 2925 5175 3300
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 3375 1275 4575 2550
+2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4725 2325 3600 1125
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2550 2400 4275 2925
+2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4275 2700 2700 2175
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 2175 3300 4125 3150
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 1
+ 3975 3300
+2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 4050 3300 2250 3450
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 5475 525 7050 525
+2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 1 0 2
+ 1 1 1.00 60.00 120.00
+ 6975 1125 5550 1125
+4 0 -1 0 0 2 14 0.0000 4 150 645 5700 3075 Server\001
+4 0 -1 0 0 2 14 0.0000 4 150 675 900 1200 Clients\001
+4 0 -1 0 0 2 14 0.0000 4 195 570 5850 300 Query\001
+4 0 -1 0 0 2 14 0.0000 4 195 570 5850 975 Reply\001
+4 0 -1 0 0 2 14 0.0000 4 150 2370 2400 4500 The Client-server model\001
diff --git a/system/doc/design_principles/clientserver.gif b/system/doc/design_principles/clientserver.gif
new file mode 100644
index 0000000000..371ece4c12
--- /dev/null
+++ b/system/doc/design_principles/clientserver.gif
Binary files differ
diff --git a/system/doc/design_principles/clientserver.ps b/system/doc/design_principles/clientserver.ps
new file mode 100644
index 0000000000..7e4e98152e
--- /dev/null
+++ b/system/doc/design_principles/clientserver.ps
@@ -0,0 +1,199 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: clientserver.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 12:48:28 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 370 264
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-54.0 272.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Ellipse
+n 3150 750 404 404 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 2175 2025 404 404 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 1650 3525 404 404 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 5025 2925 404 404 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+gs clippath
+4496 2422 m 4556 2530 l 4452 2464 l 4563 2581 l 4607 2540 l cp clip
+n 3375 1275 m 4575 2550 l gs col-1 s gr gr
+
+% arrowhead
+n 4496 2422 m 4556 2530 l 4452 2464 l 4474 2443 l 4496 2422 l cp gs 0.00 setgray ef gr col-1 s
+% Polyline
+ [66.7] 0 sd
+gs clippath
+3679 1253 m 3618 1144 l 3722 1212 l 3612 1094 l 3568 1135 l cp clip
+n 4725 2325 m 3600 1125 l gs col-1 s gr gr
+ [] 0 sd
+% arrowhead
+n 3679 1253 m 3618 1144 l 3722 1212 l 3701 1232 l 3679 1253 l cp gs 0.00 setgray ef gr col-1 s
+% Polyline
+gs clippath
+4143 2853 m 4249 2917 l 4126 2911 l 4281 2958 l 4298 2901 l cp clip
+n 2550 2400 m 4275 2925 l gs col-1 s gr gr
+
+% arrowhead
+n 4143 2853 m 4249 2917 l 4126 2911 l 4134 2882 l 4143 2853 l cp gs 0.00 setgray ef gr col-1 s
+% Polyline
+ [66.7] 0 sd
+gs clippath
+2830 2250 m 2725 2183 l 2849 2193 l 2695 2142 l 2676 2199 l cp clip
+n 4275 2700 m 2700 2175 l gs col-1 s gr gr
+ [] 0 sd
+% arrowhead
+n 2830 2250 m 2725 2183 l 2849 2193 l 2839 2221 l 2830 2250 l cp gs 0.00 setgray ef gr col-1 s
+% Polyline
+gs clippath
+3976 3131 m 4098 3152 l 3981 3191 l 4142 3179 l 4138 3119 l cp clip
+n 2175 3300 m 4125 3150 l gs col-1 s gr gr
+
+% arrowhead
+n 3976 3131 m 4098 3152 l 3981 3191 l 3978 3161 l 3976 3131 l cp gs 0.00 setgray ef gr col-1 s
+% Polyline
+n 3975 3300 m 3975 3300 l gs col-1 s gr
+% Polyline
+ [66.7] 0 sd
+gs clippath
+2399 3468 m 2276 3447 l 2394 3408 l 2233 3421 l 2238 3481 l cp clip
+n 4050 3300 m 2250 3450 l gs col-1 s gr gr
+ [] 0 sd
+% arrowhead
+n 2399 3468 m 2276 3447 l 2394 3408 l 2396 3438 l 2399 3468 l cp gs 0.00 setgray ef gr col-1 s
+% Polyline
+gs clippath
+6903 495 m 7023 525 l 6903 555 l 7065 555 l 7065 495 l cp clip
+n 5475 525 m 7050 525 l gs col-1 s gr gr
+
+% arrowhead
+n 6903 495 m 7023 525 l 6903 555 l 6903 525 l 6903 495 l cp gs 0.00 setgray ef gr col-1 s
+% Polyline
+ [66.7] 0 sd
+gs clippath
+5697 1155 m 5577 1125 l 5697 1095 l 5535 1095 l 5535 1155 l cp clip
+n 6975 1125 m 5550 1125 l gs col-1 s gr gr
+ [] 0 sd
+% arrowhead
+n 5697 1155 m 5577 1125 l 5697 1095 l 5697 1125 l 5697 1155 l cp gs 0.00 setgray ef gr col-1 s
+/Times-Bold ff 210.00 scf sf
+5700 3075 m
+gs 1 -1 sc (Server) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+900 1200 m
+gs 1 -1 sc (Clients) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+5850 300 m
+gs 1 -1 sc (Query) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+5850 975 m
+gs 1 -1 sc (Reply) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+2400 4500 m
+gs 1 -1 sc (The Client-server model) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/des_princ.xml b/system/doc/design_principles/des_princ.xml
new file mode 100644
index 0000000000..977eda49b5
--- /dev/null
+++ b/system/doc/design_principles/des_princ.xml
@@ -0,0 +1,285 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Overview</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>des_princ.xml</file>
+ </header>
+ <p>The <em>OTP Design Principles</em> is a set of principles for how
+ to structure Erlang code in terms of processes, modules and
+ directories.</p>
+
+ <section>
+ <title>Supervision Trees</title>
+ <p>A basic concept in Erlang/OTP is the <em>supervision tree</em>.
+ This is a process structuring model based on the idea of
+ <em>workers</em> and <em>supervisors</em>.</p>
+ <list type="bulleted">
+ <item>Workers are processes which perform computations, that is,
+ they do the actual work.</item>
+ <item>Supervisors are processes which monitor the behaviour of
+ workers. A supervisor can restart a worker if something goes
+ wrong.</item>
+ <item>The supervision tree is a hierarchical arrangement of
+ code into supervisors and workers, making it possible to
+ design and program fault-tolerant software.</item>
+ </list>
+ <marker id="sup6"></marker>
+ <image file="../design_principles/sup6.gif">
+ <icaption>Supervision Tree</icaption>
+ </image>
+ <p>In the figure above, square boxes represents supervisors and
+ circles represent workers.</p>
+ </section>
+
+ <section>
+ <title>Behaviours</title>
+ <p>In a supervision tree, many of the processes have similar
+ structures, they follow similar patterns. For example,
+ the supervisors are very similar in structure. The only difference
+ between them is which child processes they supervise. Also, many
+ of the workers are servers in a server-client relation, finite
+ state machines, or event handlers such as error loggers.</p>
+ <p><em>Behaviours</em> are formalizations of these common patterns.
+ The idea is to divide the code for a process in a generic part
+ (a behaviour module) and a specific part (a <em>callback module</em>).</p>
+ <p>The behaviour module is part of Erlang/OTP. To implement a
+ process such as a supervisor, the user only has to implement
+ the callback module which should export a pre-defined set of
+ functions, the <em>callback functions</em>.</p>
+ <p>An example to illustrate how code can be divided into a generic
+ and a specific part: Consider the following code (written in
+ plain Erlang) for a simple server, which keeps track of a number
+ of "channels". Other processes can allocate and free the channels
+ by calling the functions <c>alloc/0</c> and <c>free/1</c>,
+ respectively.</p>
+ <marker id="ch1"></marker>
+ <code type="none">
+-module(ch1).
+-export([start/0]).
+-export([alloc/0, free/1]).
+-export([init/0]).
+
+start() ->
+ spawn(ch1, init, []).
+
+alloc() ->
+ ch1 ! {self(), alloc},
+ receive
+ {ch1, Res} ->
+ Res
+ end.
+
+free(Ch) ->
+ ch1 ! {free, Ch},
+ ok.
+
+init() ->
+ register(ch1, self()),
+ Chs = channels(),
+ loop(Chs).
+
+loop(Chs) ->
+ receive
+ {From, alloc} ->
+ {Ch, Chs2} = alloc(Chs),
+ From ! {ch1, Ch},
+ loop(Chs2);
+ {free, Ch} ->
+ Chs2 = free(Ch, Chs),
+ loop(Chs2)
+ end.</code>
+ <p>The code for the server can be rewritten into a generic part
+ <c>server.erl</c>:</p>
+ <code type="none">
+-module(server).
+-export([start/1]).
+-export([call/2, cast/2]).
+-export([init/1]).
+
+start(Mod) ->
+ spawn(server, init, [Mod]).
+
+call(Name, Req) ->
+ Name ! {call, self(), Req},
+ receive
+ {Name, Res} ->
+ Res
+ end.
+
+cast(Name, Req) ->
+ Name ! {cast, Req},
+ ok.
+
+init(Mod) ->
+ register(Mod, self()),
+ State = Mod:init(),
+ loop(Mod, State).
+
+loop(Mod, State) ->
+ receive
+ {call, From, Req} ->
+ {Res, State2} = Mod:handle_call(Req, State),
+ From ! {Mod, Res},
+ loop(Mod, State2);
+ {cast, Req} ->
+ State2 = Mod:handle_cast(Req, State),
+ loop(Mod, State2)
+ end.</code>
+ <p>and a callback module <c>ch2.erl</c>:</p>
+ <code type="none">
+-module(ch2).
+-export([start/0]).
+-export([alloc/0, free/1]).
+-export([init/0, handle_call/2, handle_cast/2]).
+
+start() ->
+ server:start(ch2).
+
+alloc() ->
+ server:call(ch2, alloc).
+
+free(Ch) ->
+ server:cast(ch2, {free, Ch}).
+
+init() ->
+ channels().
+
+handle_call(alloc, Chs) ->
+ alloc(Chs). % => {Ch,Chs2}
+
+handle_cast({free, Ch}, Chs) ->
+ free(Ch, Chs). % => Chs2</code>
+ <p>Note the following:</p>
+ <list type="bulleted">
+ <item>The code in <c>server</c> can be re-used to build many
+ different servers.</item>
+ <item>The name of the server, in this example the atom
+ <c>ch2</c>, is hidden from the users of the client functions.
+ This means the name can be changed without affecting them.</item>
+ <item>The protcol (messages sent to and received from the server)
+ is hidden as well. This is good programming practice and allows
+ us to change the protocol without making changes to code using
+ the interface functions.</item>
+ <item>We can extend the functionality of <c>server</c>, without
+ having to change <c>ch2</c> or any other callback module.</item>
+ </list>
+ <p>(In <c>ch1.erl</c> and <c>ch2.erl</c> above, the implementation
+ of <c>channels/0</c>, <c>alloc/1</c> and <c>free/2</c> has been
+ intentionally left out, as it is not relevant to the example.
+ For completeness, one way to write these functions are given
+ below. Note that this is an example only, a realistic
+ implementation must be able to handle situations like running out
+ of channels to allocate etc.)</p>
+ <code type="none">
+channels() ->
+ {_Allocated = [], _Free = lists:seq(1,100)}.
+
+alloc({Allocated, [H|T] = _Free}) ->
+ {H, {[H|Allocated], T}}.
+
+free(Ch, {Alloc, Free} = Channels) ->
+ case lists:member(Ch, Alloc) of
+ true ->
+ {lists:delete(Ch, Alloc), [Ch|Free]};
+ false ->
+ Channels
+ end. </code>
+ <p>Code written without making use of behaviours may be more
+ efficient, but the increased efficiency will be at the expense of
+ generality. The ability to manage all applications in the system
+ in a consistent manner is very important.</p>
+ <p>Using behaviours also makes it easier to read and understand
+ code written by other programmers. Ad hoc programming structures,
+ while possibly more efficient, are always more difficult to
+ understand.</p>
+ <p>The module <c>server</c> corresponds, greatly simplified,
+ to the Erlang/OTP behaviour <c>gen_server</c>.</p>
+ <p>The standard Erlang/OTP behaviours are:</p>
+ <taglist>
+ <tag><seealso marker="gen_server_concepts">gen_server</seealso></tag>
+ <item>For implementing the server of a client-server relation.</item>
+ <tag><seealso marker="fsm">gen_fsm</seealso></tag>
+ <item>For implementing finite state machines.</item>
+ <tag><seealso marker="events">gen_event</seealso></tag>
+ <item>For implementing event handling functionality.</item>
+ <tag><seealso marker="sup_princ">supervisor</seealso></tag>
+ <item>For implementing a supervisor in a supervision tree.</item>
+ </taglist>
+ <p>The compiler understands the module attribute
+ <c>-behaviour(Behaviour)</c> and issues warnings about
+ missing callback functions. Example:</p>
+ <code type="none">
+-module(chs3).
+-behaviour(gen_server).
+...
+
+3> c(chs3).
+./chs3.erl:10: Warning: undefined call-back function handle_call/3
+{ok,chs3}</code>
+ </section>
+
+ <section>
+ <title>Applications</title>
+ <p>Erlang/OTP comes with a number of components, each implementing
+ some specific functionality. Components are with Erlang/OTP
+ terminology called <em>applications</em>. Examples of Erlang/OTP
+ applications are Mnesia, which has everything needed for
+ programming database services, and Debugger which is used to
+ debug Erlang programs. The minimal system based on Erlang/OTP
+ consists of the applications Kernel and STDLIB.</p>
+ <p>The application concept applies both to program structure
+ (processes) and directory structure (modules).</p>
+ <p>The simplest kind of application does not have any processes,
+ but consists of a collection of functional modules. Such an
+ application is called a <em>library application</em>. An example
+ of a library application is STDLIB.</p>
+ <p>An application with processes is easiest implemented as a
+ supervision tree using the standard behaviours.</p>
+ <p>How to program applications is described in
+ <seealso marker="applications">Applications</seealso>.</p>
+ </section>
+
+ <section>
+ <title>Releases</title>
+ <p>A <em>release</em> is a complete system made out from a subset of
+ the Erlang/OTP applications and a set of user-specific
+ applications.</p>
+ <p>How to program releases is described in
+ <seealso marker="release_structure">Releases</seealso>.</p>
+ <p>How to install a release in a target environment is described
+ in the chapter about Target Systems in System Principles.</p>
+ </section>
+
+ <section>
+ <title>Release Handling</title>
+ <p><em>Release handling</em> is upgrading and downgrading between
+ different versions of a release, in a (possibly) running system.
+ How to do this is described in
+ <seealso marker="release_handling">Release Handling</seealso>.</p>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/dist1.fig b/system/doc/design_principles/dist1.fig
new file mode 100644
index 0000000000..ffdb112d71
--- /dev/null
+++ b/system/doc/design_principles/dist1.fig
@@ -0,0 +1,20 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 2025 525 2775 1275
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2400 900 318 318 2400 900 2625 1125
+4 0 -1 0 0 0 12 0.0000 4 180 255 2272 945 cp2\001
+-6
+6 3375 525 4125 1275
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3750 900 318 318 3750 900 3975 1125
+4 0 -1 0 0 0 12 0.0000 4 180 255 3622 945 cp3\001
+-6
+6 675 525 1425 1575
+6 675 525 1425 1275
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1050 900 318 318 1050 900 1275 1125
+4 0 -1 0 0 0 12 0.0000 4 180 255 922 945 cp1\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 810 1500 myapp\001
+-6
diff --git a/system/doc/design_principles/dist1.gif b/system/doc/design_principles/dist1.gif
new file mode 100644
index 0000000000..b2cde85841
--- /dev/null
+++ b/system/doc/design_principles/dist1.gif
Binary files differ
diff --git a/system/doc/design_principles/dist1.ps b/system/doc/design_principles/dist1.ps
new file mode 100644
index 0000000000..3b841d2cd4
--- /dev/null
+++ b/system/doc/design_principles/dist1.ps
@@ -0,0 +1,131 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: dist1.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 13:13:44 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 202 58
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-43.0 92.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Ellipse
+n 2400 900 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+2272 945 m
+gs 1 -1 sc (cp2) col-1 sh gr
+% Ellipse
+n 3750 900 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+3622 945 m
+gs 1 -1 sc (cp3) col-1 sh gr
+% Ellipse
+n 1050 900 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+922 945 m
+gs 1 -1 sc (cp1) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+810 1500 m
+gs 1 -1 sc (myapp) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/dist2.fig b/system/doc/design_principles/dist2.fig
new file mode 100644
index 0000000000..973cbc4a31
--- /dev/null
+++ b/system/doc/design_principles/dist2.fig
@@ -0,0 +1,41 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 675 525 1425 1575
+6 675 525 1425 1275
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1050 900 318 318 1050 900 1275 1125
+4 0 -1 0 0 0 12 0.0000 4 180 255 922 945 cp1\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 810 1500 myapp\001
+-6
+6 2025 525 4125 1275
+6 2025 525 2775 1275
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2400 900 318 318 2400 900 2625 1125
+4 0 -1 0 0 0 12 0.0000 4 180 255 2272 945 cp2\001
+-6
+6 3375 525 4125 1275
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3750 900 318 318 3750 900 3975 1125
+4 0 -1 0 0 0 12 0.0000 4 180 255 3622 945 cp3\001
+-6
+-6
+6 2700 3300 3450 4050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3075 3675 318 318 3075 3675 3300 3900
+4 0 -1 0 0 0 12 0.0000 4 180 255 2947 3720 cp3\001
+-6
+6 1350 3300 2100 4425
+6 1350 3300 2100 4050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1725 3675 318 318 1725 3675 1950 3900
+4 0 -1 0 0 0 12 0.0000 4 180 255 1597 3720 cp2\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 1485 4350 myapp\001
+-6
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 525 1200 1500 525
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 600 525 1575 1350
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 2325 1725 2325 2850
+4 0 -1 0 0 0 12 0.0000 4 135 480 2550 2325 5 secs.\001
diff --git a/system/doc/design_principles/dist2.gif b/system/doc/design_principles/dist2.gif
new file mode 100644
index 0000000000..8351e8b7f0
--- /dev/null
+++ b/system/doc/design_principles/dist2.gif
Binary files differ
diff --git a/system/doc/design_principles/dist2.ps b/system/doc/design_principles/dist2.ps
new file mode 100644
index 0000000000..6fe592a4fc
--- /dev/null
+++ b/system/doc/design_principles/dist2.ps
@@ -0,0 +1,160 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: dist2.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 13:13:55 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 215 233
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-30.0 263.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Ellipse
+n 1050 900 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+922 945 m
+gs 1 -1 sc (cp1) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+810 1500 m
+gs 1 -1 sc (myapp) col-1 sh gr
+% Ellipse
+n 2400 900 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+2272 945 m
+gs 1 -1 sc (cp2) col-1 sh gr
+% Ellipse
+n 3750 900 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+3622 945 m
+gs 1 -1 sc (cp3) col-1 sh gr
+% Ellipse
+n 3075 3675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+2947 3720 m
+gs 1 -1 sc (cp3) col-1 sh gr
+% Ellipse
+n 1725 3675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+1597 3720 m
+gs 1 -1 sc (cp2) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+1485 4350 m
+gs 1 -1 sc (myapp) col-1 sh gr
+% Polyline
+n 525 1200 m 1500 525 l gs col-1 s gr
+% Polyline
+n 600 525 m 1575 1350 l gs col-1 s gr
+% Polyline
+gs clippath
+2355 2703 m 2325 2823 l 2295 2703 l 2295 2865 l 2355 2865 l cp clip
+n 2325 1725 m 2325 2850 l gs col-1 s gr gr
+
+% arrowhead
+n 2355 2703 m 2325 2823 l 2295 2703 l col-1 s
+/Times-Roman ff 180.00 scf sf
+2550 2325 m
+gs 1 -1 sc (5 secs.) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/dist3.fig b/system/doc/design_principles/dist3.fig
new file mode 100644
index 0000000000..d7e32d0887
--- /dev/null
+++ b/system/doc/design_principles/dist3.fig
@@ -0,0 +1,33 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 1275 300 2325 1125
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1275 975 2250 300
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1350 300 2325 1125
+-6
+6 2775 300 3525 1050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3150 675 318 318 3150 675 3375 900
+4 0 -1 0 0 0 12 0.0000 4 180 255 3022 720 cp3\001
+-6
+6 1425 300 2175 1425
+6 1425 300 2175 1050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1800 675 318 318 1800 675 2025 900
+4 0 -1 0 0 0 12 0.0000 4 180 255 1672 720 cp2\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 1560 1350 myapp\001
+-6
+6 1950 3225 2700 4350
+6 1950 3225 2700 3975
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2325 3600 318 318 2325 3600 2550 3825
+4 0 -1 0 0 0 12 0.0000 4 180 255 2197 3645 cp3\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 2085 4275 myapp\001
+-6
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 2325 1725 2325 2850
+4 0 -1 0 0 0 12 0.0000 4 135 480 2550 2325 5 secs.\001
diff --git a/system/doc/design_principles/dist3.gif b/system/doc/design_principles/dist3.gif
new file mode 100644
index 0000000000..e95958cc16
--- /dev/null
+++ b/system/doc/design_principles/dist3.gif
Binary files differ
diff --git a/system/doc/design_principles/dist3.ps b/system/doc/design_principles/dist3.ps
new file mode 100644
index 0000000000..3e0e93f5db
--- /dev/null
+++ b/system/doc/design_principles/dist3.ps
@@ -0,0 +1,148 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: dist3.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 13:14:01 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 134 242
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-75.0 259.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Polyline
+n 1275 975 m 2250 300 l gs col-1 s gr
+% Polyline
+n 1350 300 m 2325 1125 l gs col-1 s gr
+% Ellipse
+n 3150 675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+3022 720 m
+gs 1 -1 sc (cp3) col-1 sh gr
+% Ellipse
+n 1800 675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+1672 720 m
+gs 1 -1 sc (cp2) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+1560 1350 m
+gs 1 -1 sc (myapp) col-1 sh gr
+% Ellipse
+n 2325 3600 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+2197 3645 m
+gs 1 -1 sc (cp3) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+2085 4275 m
+gs 1 -1 sc (myapp) col-1 sh gr
+% Polyline
+gs clippath
+2355 2703 m 2325 2823 l 2295 2703 l 2295 2865 l 2355 2865 l cp clip
+n 2325 1725 m 2325 2850 l gs col-1 s gr gr
+
+% arrowhead
+n 2355 2703 m 2325 2823 l 2295 2703 l col-1 s
+/Times-Roman ff 180.00 scf sf
+2550 2325 m
+gs 1 -1 sc (5 secs.) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/dist4.fig b/system/doc/design_principles/dist4.fig
new file mode 100644
index 0000000000..d40be27ad6
--- /dev/null
+++ b/system/doc/design_principles/dist4.fig
@@ -0,0 +1,16 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 1425 300 2175 1050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1800 675 318 318 1800 675 2025 900
+4 0 -1 0 0 0 12 0.0000 4 180 255 1672 720 cp2\001
+-6
+6 2775 300 3525 1500
+6 2775 300 3525 1050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3150 675 318 318 3150 675 3375 900
+4 0 -1 0 0 0 12 0.0000 4 180 255 3022 720 cp3\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 2910 1425 myapp\001
+-6
diff --git a/system/doc/design_principles/dist4.gif b/system/doc/design_principles/dist4.gif
new file mode 100644
index 0000000000..b1d996b861
--- /dev/null
+++ b/system/doc/design_principles/dist4.gif
Binary files differ
diff --git a/system/doc/design_principles/dist4.ps b/system/doc/design_principles/dist4.ps
new file mode 100644
index 0000000000..9bcf3dd880
--- /dev/null
+++ b/system/doc/design_principles/dist4.ps
@@ -0,0 +1,125 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: dist4.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 13:14:06 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 121 67
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-88.0 88.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Ellipse
+n 1800 675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+1672 720 m
+gs 1 -1 sc (cp2) col-1 sh gr
+% Ellipse
+n 3150 675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+3022 720 m
+gs 1 -1 sc (cp3) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+2910 1425 m
+gs 1 -1 sc (myapp) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/dist5.fig b/system/doc/design_principles/dist5.fig
new file mode 100644
index 0000000000..77f2d74c59
--- /dev/null
+++ b/system/doc/design_principles/dist5.fig
@@ -0,0 +1,40 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 750 3000 4200 4050
+6 2100 3000 2850 3750
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2475 3375 318 318 2475 3375 2700 3600
+4 0 -1 0 0 0 12 0.0000 4 180 255 2347 3420 cp2\001
+-6
+6 3450 3000 4200 3750
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3825 3375 318 318 3825 3375 4050 3600
+4 0 -1 0 0 0 12 0.0000 4 180 255 3697 3420 cp3\001
+-6
+6 750 3000 1500 4050
+6 750 3000 1500 3750
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1125 3375 318 318 1125 3375 1350 3600
+4 0 -1 0 0 0 12 0.0000 4 180 255 997 3420 cp1\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 885 3975 myapp\001
+-6
+-6
+6 2100 300 2850 1050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2475 675 318 318 2475 675 2700 900
+4 0 -1 0 0 0 12 0.0000 4 180 255 2347 720 cp2\001
+-6
+6 3450 300 4200 1425
+6 3450 300 4200 1050
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3825 675 318 318 3825 675 4050 900
+4 0 -1 0 0 0 12 0.0000 4 180 255 3697 720 cp3\001
+-6
+4 0 -1 0 0 0 12 0.0000 4 135 480 3585 1350 myapp\001
+-6
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 2175 2325 1425 2925
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 1 0 2
+ 0 0 1.00 60.00 120.00
+ 3600 1350 2775 1950
+4 0 -1 0 0 0 12 0.0000 4 180 3270 750 2175 cp1: application:takeover(myapp, permanent)\001
diff --git a/system/doc/design_principles/dist5.gif b/system/doc/design_principles/dist5.gif
new file mode 100644
index 0000000000..3ef5cda3f6
--- /dev/null
+++ b/system/doc/design_principles/dist5.gif
Binary files differ
diff --git a/system/doc/design_principles/dist5.ps b/system/doc/design_principles/dist5.ps
new file mode 100644
index 0000000000..daeb56b2b7
--- /dev/null
+++ b/system/doc/design_principles/dist5.ps
@@ -0,0 +1,165 @@
+%!PS-Adobe-2.0
+%%Title: dist5.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Mon Feb 15 08:40:37 1999
+%%For: nibe@gundor (Bengt Nilsson, ETX/DN/SP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 203 286 408 506
+%%Pages: 1
+%%BeginSetup
+%%IncludeFeature: *PageSize Letter
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+158.5 527.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 792 m 0 0 l 612 0 l 612 792 l cp clip
+ 0.06000 0.06000 sc
+%%Page: 1 1
+7.500 slw
+% Ellipse
+n 2475 3375 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+2347 3420 m
+gs 1 -1 sc (cp2) col-1 sh gr
+% Ellipse
+n 3825 3375 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+3697 3420 m
+gs 1 -1 sc (cp3) col-1 sh gr
+% Ellipse
+n 1125 3375 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+997 3420 m
+gs 1 -1 sc (cp1) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+885 3975 m
+gs 1 -1 sc (myapp) col-1 sh gr
+% Ellipse
+n 2475 675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+2347 720 m
+gs 1 -1 sc (cp2) col-1 sh gr
+% Ellipse
+n 3825 675 318 318 0 360 DrawEllipse gs col-1 s gr
+
+/Times-Roman ff 180.00 scf sf
+3697 720 m
+gs 1 -1 sc (cp3) col-1 sh gr
+/Times-Roman ff 180.00 scf sf
+3585 1350 m
+gs 1 -1 sc (myapp) col-1 sh gr
+% Polyline
+gs clippath
+1559 2857 m 1446 2908 l 1521 2810 l 1395 2911 l 1432 2958 l cp clip
+n 2175 2325 m 1425 2925 l gs col-1 s gr gr
+
+% arrowhead
+n 1559 2857 m 1446 2908 l 1521 2810 l col-1 s
+% Polyline
+gs clippath
+2912 1888 m 2796 1934 l 2876 1839 l 2745 1935 l 2781 1983 l cp clip
+n 3600 1350 m 2775 1950 l gs col-1 s gr gr
+
+% arrowhead
+n 2912 1888 m 2796 1934 l 2876 1839 l col-1 s
+/Times-Roman ff 180.00 scf sf
+750 2175 m
+gs 1 -1 sc (cp1: application:takeover\(myapp, permanent\)) col-1 sh gr
+showpage
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/distributed_applications.xml b/system/doc/design_principles/distributed_applications.xml
new file mode 100644
index 0000000000..39a24b3598
--- /dev/null
+++ b/system/doc/design_principles/distributed_applications.xml
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Distributed Applications</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>distributed_applications.xml</file>
+ </header>
+
+ <section>
+ <title>Definition</title>
+ <p>In a distributed system with several Erlang nodes, there may be
+ a need to control applications in a distributed manner. If
+ the node, where a certain application is running, goes down,
+ the application should be restarted at another node.</p>
+ <p>Such an application is called a <em>distributed application</em>.
+ Note that it is the control of the application which is
+ distributed, all applications can of course be distributed in
+ the sense that they, for example, use services on other nodes.</p>
+ <p>Because a distributed application may move between nodes, some
+ addressing mechanism is required to ensure that it can be
+ addressed by other applications, regardless on which node it
+ currently executes. This issue is not addressed here, but the
+ Kernel module <c>global</c> or STDLIB module <c>pg</c> can be
+ used for this purpose.</p>
+ </section>
+
+ <section>
+ <title>Specifying Distributed Applications</title>
+ <p>Distributed applications are controlled by both the application
+ controller and a distributed application controller process,
+ <c>dist_ac</c>. Both these processes are part of the <c>kernel</c>
+ application. Therefore, distributed applications are specified by
+ configuring the <c>kernel</c> application, using the following
+ configuration parameter (see also <c>kernel(6)</c>):</p>
+ <taglist>
+ <tag><c>distributed = [{Application, [Timeout,] NodeDesc}]</c></tag>
+ <item>
+ <p>Specifies where the application <c>Application = atom()</c>
+ may execute. <c>NodeDesc = [Node | {Node,...,Node}]</c> is
+ a list of node names in priority order. The order between
+ nodes in a tuple is undefined.</p>
+ <p><c>Timeout = integer()</c> specifies how many milliseconds to
+ wait before restarting the application at another node.
+ Defaults to 0.</p>
+ </item>
+ </taglist>
+ <p>For distribution of application control to work properly,
+ the nodes where a distributed application may run must contact
+ each other and negotiate where to start the application. This is
+ done using the following <c>kernel</c> configuration parameters:</p>
+ <taglist>
+ <tag><c>sync_nodes_mandatory = [Node]</c></tag>
+ <item>Specifies which other nodes must be started (within
+ the timeout specified by <c>sync_nodes_timeout</c>.</item>
+ <tag><c>sync_nodes_optional = [Node]</c></tag>
+ <item>Specifies which other nodes can be started (within
+ the timeout specified by <c>sync_nodes_timeout</c>.</item>
+ <tag><c>sync_nodes_timeout = integer() | infinity</c></tag>
+ <item>Specifies how many milliseconds to wait for the other nodes
+ to start.</item>
+ </taglist>
+ <p>When started, the node will wait for all nodes specified by
+ <c>sync_nodes_mandatory</c> and <c>sync_nodes_optional</c> to
+ come up. When all nodes have come up, or when all mandatory nodes
+ have come up and the time specified by <c>sync_nodes_timeout</c>
+ has elapsed, all applications will be started. If not all
+ mandatory nodes have come up, the node will terminate.</p>
+ <p>Example: An application <c>myapp</c> should run at the node
+ <c>cp1@cave</c>. If this node goes down, <c>myapp</c> should
+ be restarted at <c>cp2@cave</c> or <c>cp3@cave</c>. A system
+ configuration file <c>cp1.config</c> for <c>cp1@cave</c> could
+ look like:</p>
+ <code type="none">
+[{kernel,
+ [{distributed, [{myapp, 5000, [cp1@cave, {cp2@cave, cp3@cave}]}]},
+ {sync_nodes_mandatory, [cp2@cave, cp3@cave]},
+ {sync_nodes_timeout, 5000}
+ ]
+ }
+].</code>
+ <p>The system configuration files for <c>cp2@cave</c> and
+ <c>cp3@cave</c> are identical, except for the list of mandatory
+ nodes which should be <c>[cp1@cave, cp3@cave]</c> for
+ <c>cp2@cave</c> and <c>[cp1@cave, cp2@cave]</c> for
+ <c>cp3@cave</c>.</p>
+ <note>
+ <p>All involved nodes must have the same value for
+ <c>distributed</c> and <c>sync_nodes_timeout</c>, or
+ the behaviour of the system is undefined.</p>
+ </note>
+ </section>
+
+ <section>
+ <title>Starting and Stopping Distributed Applications</title>
+ <p>When all involved (mandatory) nodes have been started,
+ the distributed application can be started by calling
+ <c>application:start(Application)</c> at <em>all of these nodes.</em></p>
+ <p>It is of course also possible to use a boot script (see
+ <seealso marker="release_structure">Releases</seealso>) which
+ automatically starts the application.</p>
+ <p>The application will be started at the first node, specified
+ by the <c>distributed</c> configuration parameter, which is up
+ and running. The application is started as usual. That is, an
+ application master is created and calls the application callback
+ function:</p>
+ <code type="none">
+Module:start(normal, StartArgs)</code>
+ <p>Example: Continuing the example from the previous section,
+ the three nodes are started, specifying the system configuration
+ file:</p>
+ <pre>
+> <input>erl -sname cp1 -config cp1</input>
+> <input>erl -sname cp2 -config cp2</input>
+> <input>erl -sname cp3 -config cp3</input></pre>
+ <p>When all nodes are up and running, <c>myapp</c> can be started.
+ This is achieved by calling <c>application:start(myapp)</c> at
+ all three nodes. It is then started at <c>cp1</c>, as shown in
+ the figure below.</p>
+ <marker id="dist1"></marker>
+ <image file="../design_principles/dist1.gif">
+ <icaption>Application myapp - Situation 1</icaption>
+ </image>
+ <p>Similarly, the application must be stopped by calling
+ <c>application:stop(Application)</c> at all involved nodes.</p>
+ </section>
+
+ <section>
+ <title>Failover</title>
+ <p>If the node where the application is running goes down,
+ the application is restarted (after the specified timeout) at
+ the first node, specified by the <c>distributed</c> configuration
+ parameter, which is up and running. This is called a
+ <em>failover</em>.</p>
+ <p>The application is started the normal way at the new node,
+ that is, by the application master calling:</p>
+ <code type="none">
+Module:start(normal, StartArgs)</code>
+ <p>Exception: If the application has the <c>start_phases</c> key
+ defined (see <seealso marker="included_applications">Included Applications</seealso>), then the application is instead started
+ by calling:</p>
+ <code type="none">
+Module:start({failover, Node}, StartArgs)</code>
+ <p>where <c>Node</c> is the terminated node.</p>
+ <p>Example: If <c>cp1</c> goes down, the system checks which one of
+ the other nodes, <c>cp2</c> or <c>cp3</c>, has the least number of
+ running applications, but waits for 5 seconds for <c>cp1</c> to
+ restart. If <c>cp1</c> does not restart and <c>cp2</c> runs fewer
+ applications than <c>cp3,</c> then <c>myapp</c> is restarted on
+ <c>cp2</c>.</p>
+ <marker id="dist2"></marker>
+ <image file="../design_principles/dist2.gif">
+ <icaption>Application myapp - Situation 2</icaption>
+ </image>
+ <p>Suppose now that <c>cp2</c> goes down as well and does not
+ restart within 5 seconds. <c>myapp</c> is now restarted on
+ <c>cp3</c>.</p>
+ <marker id="dist3"></marker>
+ <image file="../design_principles/dist3.gif">
+ <icaption>Application myapp - Situation 3</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>Takeover</title>
+ <p>If a node is started, which has higher priority according
+ to <c>distributed</c>, than the node where a distributed
+ application is currently running, the application will be
+ restarted at the new node and stopped at the old node. This is
+ called a <em>takeover</em>.</p>
+ <p>The application is started by the application master calling:</p>
+ <code type="none">
+Module:start({takeover, Node}, StartArgs)</code>
+ <p>where <c>Node</c> is the old node.</p>
+ <p>Example: If <c>myapp</c> is running at <c>cp3</c>, and if
+ <c>cp2</c> now restarts, it will not restart <c>myapp</c>,
+ because the order between nodes <c>cp2</c> and <c>cp3</c> is
+ undefined.</p>
+ <marker id="dist4"></marker>
+ <image file="../design_principles/dist4.gif">
+ <icaption>Application myapp - Situation 4</icaption>
+ </image>
+ <p>However, if <c>cp1</c> restarts as well, the function
+ <c>application:takeover/2</c> moves <c>myapp</c> to <c>cp1</c>,
+ because <c>cp1</c> has a higher priority than <c>cp3</c> for this
+ application. In this case,
+ <c>Module:start({takeover, cp3@cave}, StartArgs)</c> is executed
+ at <c>cp1</c> to start the application.</p>
+ <marker id="dist5"></marker>
+ <image file="../design_principles/dist5.gif">
+ <icaption>Application myapp - Situation 5</icaption>
+ </image>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/events.xml b/system/doc/design_principles/events.xml
new file mode 100644
index 0000000000..5579f1e459
--- /dev/null
+++ b/system/doc/design_principles/events.xml
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Gen_Event Behaviour</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>events.xml</file>
+ </header>
+ <marker id="gen_event"></marker>
+ <p>This chapter should be read in conjunction with
+ <c>gen_event(3)</c>, where all interface functions and callback
+ functions are described in detail.</p>
+
+ <section>
+ <title>Event Handling Principles</title>
+ <p>In OTP, an <em>event manager</em> is a named object to which
+ events can be sent. An <em>event</em> could be, for example,
+ an error, an alarm or some information that should be logged.</p>
+ <p>In the event manager, zero, one or several <em>event handlers</em> are installed. When the event manager is notified
+ about an event, the event will be processed by all the installed
+ event handlers. For example, an event manager for handling errors
+ can by default have a handler installed which writes error
+ messages to the terminal. If the error messages during a certain
+ period should be saved to a file as well, the user adds another
+ event handler which does this. When logging to file is no longer
+ necessary, this event handler is deleted.</p>
+ <p>An event manager is implemented as a process and each event
+ handler is implemented as a callback module.</p>
+ <p>The event manager essentially maintains a list of
+ <c>{Module, State}</c> pairs, where each <c>Module</c> is an
+ event handler, and <c>State</c> the internal state of that event
+ handler.</p>
+ </section>
+
+ <section>
+ <title>Example</title>
+ <p>The callback module for the event handler writing error messages
+ to the terminal could look like:</p>
+ <code type="none">
+-module(terminal_logger).
+-behaviour(gen_event).
+
+-export([init/1, handle_event/2, terminate/2]).
+
+init(_Args) ->
+ {ok, []}.
+
+handle_event(ErrorMsg, State) ->
+ io:format("***Error*** ~p~n", [ErrorMsg]),
+ {ok, State}.
+
+terminate(_Args, _State) ->
+ ok.</code>
+ <p>The callback module for the event handler writing error messages
+ to a file could look like:</p>
+ <code type="none">
+-module(file_logger).
+-behaviour(gen_event).
+
+-export([init/1, handle_event/2, terminate/2]).
+
+init(File) ->
+ {ok, Fd} = file:open(File, read),
+ {ok, Fd}.
+
+handle_event(ErrorMsg, Fd) ->
+ io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
+ {ok, Fd}.
+
+terminate(_Args, Fd) ->
+ file:close(Fd).</code>
+ <p>The code is explained in the next sections.</p>
+ </section>
+
+ <section>
+ <marker id="mgr"></marker>
+ <title>Starting an Event Manager</title>
+ <p>To start an event manager for handling errors, as described in
+ the example above, call the following function:</p>
+ <code type="none">
+gen_event:start_link({local, error_man})</code>
+ <p>This function spawns and links to a new process, an event
+ manager.</p>
+ <p>The argument, <c>{local, error_man}</c> specifies the name. In
+ this case, the event manager will be locally registered as
+ <c>error_man</c>.</p>
+ <p>If the name is omitted, the event manager is not registered.
+ Instead its pid must be used. The name could also be given
+ as <c>{global, Name}</c>, in which case the event manager is
+ registered using <c>global:register_name/2</c>.</p>
+ <p><c>gen_event:start_link</c> must be used if the event manager is
+ part of a supervision tree, i.e. is started by a supervisor.
+ There is another function <c>gen_event:start</c> to start a
+ stand-alone event manager, i.e. an event manager which is not
+ part of a supervision tree.</p>
+ </section>
+
+ <section>
+ <title>Adding an Event Handler</title>
+ <p>Here is an example using the shell on how to start an event
+ manager and add an event handler to it:</p>
+ <pre>
+1> <input>gen_event:start({local, error_man}).</input>
+{ok,&lt;0.31.0>}
+2> <input>gen_event:add_handler(error_man, terminal_logger, []).</input>
+ok</pre>
+ <p>This function sends a message to the event manager registered as
+ <c>error_man</c>, telling it to add the event handler
+ <c>terminal_logger</c>. The event manager will call the callback
+ function <c>terminal_logger:init([])</c>, where the argument []
+ is the third argument to <c>add_handler</c>. <c>init</c> is
+ expected to return <c>{ok, State}</c>, where <c>State</c> is
+ the internal state of the event handler.</p>
+ <code type="none">
+init(_Args) ->
+ {ok, []}.</code>
+ <p>Here, <c>init</c> does not need any input data and ignores its
+ argument. Also, for <c>terminal_logger</c> the internal state is
+ not used. For <c>file_logger</c>, the internal state is used
+ to save the open file descriptor.</p>
+ <code type="none">
+init(File) ->
+ {ok, Fd} = file:open(File, read),
+ {ok, Fd}.</code>
+ </section>
+
+ <section>
+ <title>Notifying About Events</title>
+ <pre>
+3> <input>gen_event:notify(error_man, no_reply).</input>
+***Error*** no_reply
+ok</pre>
+ <p><c>error_man</c> is the name of the event manager and
+ <c>no_reply</c> is the event.</p>
+ <p>The event is made into a message and sent to the event manager.
+ When the event is received, the event manager calls
+ <c>handle_event(Event, State)</c> for each installed event
+ handler, in the same order as they were added. The function is
+ expected to return a tuple <c>{ok, State1}</c>, where
+ <c>State1</c> is a new value for the state of the event handler.</p>
+ <p>In <c>terminal_logger</c>:</p>
+ <code type="none">
+handle_event(ErrorMsg, State) ->
+ io:format("***Error*** ~p~n", [ErrorMsg]),
+ {ok, State}.</code>
+ <p>In <c>file_logger</c>:</p>
+ <code type="none">
+handle_event(ErrorMsg, Fd) ->
+ io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
+ {ok, Fd}.</code>
+ </section>
+
+ <section>
+ <title>Deleting an Event Handler</title>
+ <pre>
+4> <input>gen_event:delete_handler(error_man, terminal_logger, []).</input>
+ok</pre>
+ <p>This function sends a message to the event manager registered as
+ <c>error_man</c>, telling it to delete the event handler
+ <c>terminal_logger</c>. The event manager will call the callback
+ function <c>terminal_logger:terminate([], State)</c>, where
+ the argument [] is the third argument to <c>delete_handler</c>.
+ <c>terminate</c> should be the opposite of <c>init</c> and do any
+ necessary cleaning up. Its return value is ignored.</p>
+ <p>For <c>terminal_logger</c>, no cleaning up is necessary:</p>
+ <code type="none">
+terminate(_Args, _State) ->
+ ok.</code>
+ <p>For <c>file_logger</c>, the file descriptor opened in <c>init</c>
+ needs to be closed:</p>
+ <code type="none">
+terminate(_Args, Fd) ->
+ file:close(Fd).</code>
+ </section>
+
+ <section>
+ <title>Stopping</title>
+ <p>When an event manager is stopped, it will give each of
+ the installed event handlers the chance to clean up by calling
+ <c>terminate/2</c>, the same way as when deleting a handler.</p>
+
+ <section>
+ <title>In a Supervision Tree</title>
+ <p>If the event manager is part of a supervision tree, no stop
+ function is needed. The event manager will automatically be
+ terminated by its supervisor. Exactly how this is done is
+ defined by a <seealso marker="sup_princ#shutdown">shutdown strategy</seealso> set in the supervisor.</p>
+ </section>
+
+ <section>
+ <title>Stand-Alone Event Managers</title>
+ <p>An event manager can also be stopped by calling:</p>
+ <pre>
+> <input>gen_event:stop(error_man).</input>
+ok</pre>
+ </section>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/fsm.xml b/system/doc/design_principles/fsm.xml
new file mode 100644
index 0000000000..7cdd62057b
--- /dev/null
+++ b/system/doc/design_principles/fsm.xml
@@ -0,0 +1,313 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Gen_Fsm Behaviour</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>fsm.xml</file>
+ </header>
+ <p>This chapter should be read in conjunction with <c>gen_fsm(3)</c>,
+ where all interface functions and callback functions are described
+ in detail.</p>
+
+ <section>
+ <title>Finite State Machines</title>
+ <p>A finite state machine, FSM, can be described as a set of
+ relations of the form:</p>
+ <pre>
+State(S) x Event(E) -> Actions(A), State(S')</pre>
+ <p>These relations are interpreted as meaning:</p>
+ <quote>
+ <p>If we are in state <c>S</c> and the event <c>E</c> occurs, we
+ should perform the actions <c>A</c> and make a transition to
+ the state <c>S'</c>.</p>
+ </quote>
+ <p>For an FSM implemented using the <c>gen_fsm</c> behaviour,
+ the state transition rules are written as a number of Erlang
+ functions which conform to the following convention:</p>
+ <pre>
+StateName(Event, StateData) ->
+ .. code for actions here ...
+ {next_state, StateName', StateData'}</pre>
+ </section>
+
+ <section>
+ <title>Example</title>
+ <p>A door with a code lock could be viewed as an FSM. Initially,
+ the door is locked. Anytime someone presses a button, this
+ generates an event. Depending on what buttons have been pressed
+ before, the sequence so far may be correct, incomplete or wrong.</p>
+ <p>If it is correct, the door is unlocked for 30 seconds (30000 ms).
+ If it is incomplete, we wait for another button to be pressed. If
+ it is is wrong, we start all over, waiting for a new button
+ sequence.</p>
+ <p>Implementing the code lock FSM using <c>gen_fsm</c> results in
+ this callback module:</p>
+ <marker id="ex"></marker>
+ <code type="none"><![CDATA[
+-module(code_lock).
+-behaviour(gen_fsm).
+
+-export([start_link/1]).
+-export([button/1]).
+-export([init/1, locked/2, open/2]).
+
+start_link(Code) ->
+ gen_fsm:start_link({local, code_lock}, code_lock, Code, []).
+
+button(Digit) ->
+ gen_fsm:send_event(code_lock, {button, Digit}).
+
+init(Code) ->
+ {ok, locked, {[], Code}}.
+
+locked({button, Digit}, {SoFar, Code}) ->
+ case [Digit|SoFar] of
+ Code ->
+ do_unlock(),
+ {next_state, open, {[], Code}, 3000};
+ Incomplete when length(Incomplete)<length(Code) ->
+ {next_state, locked, {Incomplete, Code}};
+ _Wrong ->
+ {next_state, locked, {[], Code}}
+ end.
+
+open(timeout, State) ->
+ do_lock(),
+ {next_state, locked, State}.]]></code>
+ <p>The code is explained in the next sections.</p>
+ </section>
+
+ <section>
+ <title>Starting a Gen_Fsm</title>
+ <p>In the example in the previous section, the gen_fsm is started by
+ calling <c>code_lock:start_link(Code)</c>:</p>
+ <code type="none">
+start_link(Code) ->
+ gen_fsm:start_link({local, code_lock}, code_lock, Code, []).</code>
+ <p><c>start_link</c> calls the function <c>gen_fsm:start_link/4</c>.
+ This function spawns and links to a new process, a gen_fsm.</p>
+ <list type="bulleted">
+ <item>
+ <p>The first argument <c>{local, code_lock}</c> specifies
+ the name. In this case, the gen_fsm will be locally registered
+ as <c>code_lock</c>.</p>
+ <p>If the name is omitted, the gen_fsm is not registered.
+ Instead its pid must be used. The name could also be given as
+ <c>{global, Name}</c>, in which case the gen_fsm is registered
+ using <c>global:register_name/2</c>.</p>
+ </item>
+ <item>
+ <p>The second argument, <c>code_lock</c>, is the name of
+ the callback module, that is the module where the callback
+ functions are located.</p>
+ <p>In this case, the interface functions (<c>start_link</c> and
+ <c>button</c>) are located in the same module as the callback
+ functions (<c>init</c>, <c>locked</c> and <c>open</c>). This
+ is normally good programming practice, to have the code
+ corresponding to one process contained in one module.</p>
+ </item>
+ <item>
+ <p>The third argument, <c>Code</c>, is a term which is passed
+ as-is to the callback function <c>init</c>. Here, <c>init</c>
+ gets the correct code for the lock as indata.</p>
+ </item>
+ <item>
+ <p>The fourth argument, [], is a list of options. See
+ <c>gen_fsm(3)</c> for available options.</p>
+ </item>
+ </list>
+ <p>If name registration succeeds, the new gen_fsm process calls
+ the callback function <c>code_lock:init(Code)</c>. This function
+ is expected to return <c>{ok, StateName, StateData}</c>, where
+ <c>StateName</c> is the name of the initial state of the gen_fsm.
+ In this case <c>locked</c>, assuming the door is locked to begin
+ with. <c>StateData</c> is the internal state of the gen_fsm. (For
+ gen_fsms, the internal state is often referred to 'state data' to
+ distinguish it from the state as in states of a state machine.)
+ In this case, the state data is the button sequence so far (empty
+ to begin with) and the correct code of the lock.</p>
+ <code type="none">
+init(Code) ->
+ {ok, locked, {[], Code}}.</code>
+ <p>Note that <c>gen_fsm:start_link</c> is synchronous. It does not
+ return until the gen_fsm has been initialized and is ready to
+ receive notifications.</p>
+ <p><c>gen_fsm:start_link</c> must be used if the gen_fsm is part of
+ a supervision tree, i.e. is started by a supervisor. There is
+ another function <c>gen_fsm:start</c> to start a stand-alone
+ gen_fsm, i.e. a gen_fsm which is not part of a supervision tree.</p>
+ </section>
+
+ <section>
+ <title>Notifying About Events</title>
+ <p>The function notifying the code lock about a button event is
+ implemented using <c>gen_fsm:send_event/2</c>:</p>
+ <code type="none">
+button(Digit) ->
+ gen_fsm:send_event(code_lock, {button, Digit}).</code>
+ <p><c>code_lock</c> is the name of the gen_fsm and must agree with
+ the name used to start it. <c>{button, Digit}</c> is the actual
+ event.</p>
+ <p>The event is made into a message and sent to the gen_fsm. When
+ the event is received, the gen_fsm calls
+ <c>StateName(Event, StateData)</c> which is expected to return a
+ tuple <c>{next_state, StateName1, StateData1}</c>.
+ <c>StateName</c> is the name of the current state and
+ <c>StateName1</c> is the name of the next state to go to.
+ <c>StateData1</c> is a new value for the state data of
+ the gen_fsm.</p>
+ <code type="none"><![CDATA[
+locked({button, Digit}, {SoFar, Code}) ->
+ case [Digit|SoFar] of
+ Code ->
+ do_unlock(),
+ {next_state, open, {[], Code}, 30000};
+ Incomplete when length(Incomplete)<length(Code) ->
+ {next_state, locked, {Incomplete, Code}};
+ _Wrong ->
+ {next_state, locked, {[], Code}};
+ end.
+
+open(timeout, State) ->
+ do_lock(),
+ {next_state, locked, State}.]]></code>
+ <p>If the door is locked and a button is pressed, the complete
+ button sequence so far is compared with the correct code for
+ the lock and, depending on the result, the door is either unlocked
+ and the gen_fsm goes to state <c>open</c>, or the door remains in
+ state <c>locked</c>.</p>
+ </section>
+
+ <section>
+ <title>Timeouts</title>
+ <p>When a correct code has been givened, the door is unlocked and
+ the following tuple is returned from <c>locked/2</c>:</p>
+ <code type="none">
+{next_state, open, {[], Code}, 30000};</code>
+ <p>30000 is a timeout value in milliseconds. After 30000 ms, i.e.
+ 30 seconds, a timeout occurs. Then <c>StateName(timeout, StateData)</c> is called. In this case, the timeout occurs when
+ the door has been in state <c>open</c> for 30 seconds. After that
+ the door is locked again:</p>
+ <code type="none">
+open(timeout, State) ->
+ do_lock(),
+ {next_state, locked, State}.</code>
+ </section>
+
+ <section>
+ <title>All State Events</title>
+ <p>Sometimes an event can arrive at any state of the gen_fsm.
+ Instead of sending the message with <c>gen_fsm:send_event/2</c>
+ and writing one clause handling the event for each state function,
+ the message can be sent with <c>gen_fsm:send_all_state_event/2</c>
+ and handled with <c>Module:handle_event/3</c>:</p>
+ <code type="none">
+-module(code_lock).
+...
+-export([stop/0]).
+...
+
+stop() ->
+ gen_fsm:send_all_state_event(code_lock, stop).
+
+...
+
+handle_event(stop, _StateName, StateData) ->
+ {stop, normal, StateData}.</code>
+ </section>
+
+ <section>
+ <title>Stopping</title>
+
+ <section>
+ <title>In a Supervision Tree</title>
+ <p>If the gen_fsm is part of a supervision tree, no stop function
+ is needed. The gen_fsm will automatically be terminated by its
+ supervisor. Exactly how this is done is defined by a
+ <seealso marker="sup_princ#shutdown">shutdown strategy</seealso>
+ set in the supervisor.</p>
+ <p>If it is necessary to clean up before termination, the shutdown
+ strategy must be a timeout value and the gen_fsm must be set to
+ trap exit signals in the <c>init</c> function. When ordered
+ to shutdown, the gen_fsm will then call the callback function
+ <c>terminate(shutdown, StateName, StateData)</c>:</p>
+ <code type="none">
+init(Args) ->
+ ...,
+ process_flag(trap_exit, true),
+ ...,
+ {ok, StateName, StateData}.
+
+...
+
+terminate(shutdown, StateName, StateData) ->
+ ..code for cleaning up here..
+ ok.</code>
+ </section>
+
+ <section>
+ <title>Stand-Alone Gen_Fsms</title>
+ <p>If the gen_fsm is not part of a supervision tree, a stop
+ function may be useful, for example:</p>
+ <code type="none">
+...
+-export([stop/0]).
+...
+
+stop() ->
+ gen_fsm:send_all_state_event(code_lock, stop).
+...
+
+handle_event(stop, _StateName, StateData) ->
+ {stop, normal, StateData}.
+
+...
+
+terminate(normal, _StateName, _StateData) ->
+ ok.</code>
+ <p>The callback function handling the <c>stop</c> event returns a
+ tuple <c>{stop,normal,StateData1}</c>, where <c>normal</c>
+ specifies that it is a normal termination and <c>StateData1</c>
+ is a new value for the state data of the gen_fsm. This will
+ cause the gen_fsm to call
+ <c>terminate(normal,StateName,StateData1)</c> and then
+ terminate gracefully:</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Handling Other Messages</title>
+ <p>If the gen_fsm should be able to receive other messages than
+ events, the callback function <c>handle_info(Info, StateName, StateData)</c> must be implemented to handle them. Examples of
+ other messages are exit messages, if the gen_fsm is linked to
+ other processes (than the supervisor) and trapping exit signals.</p>
+ <code type="none">
+handle_info({'EXIT', Pid, Reason}, StateName, StateData) ->
+ ..code to handle exits here..
+ {next_state, StateName1, StateData1}.</code>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/gen_server_concepts.xml b/system/doc/design_principles/gen_server_concepts.xml
new file mode 100644
index 0000000000..8131c47a69
--- /dev/null
+++ b/system/doc/design_principles/gen_server_concepts.xml
@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Gen_Server Behaviour</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>gen_server_concepts.xml</file>
+ </header>
+ <marker id="gen_server"></marker>
+ <p>This chapter should be read in conjunction with
+ <seealso marker="stdlib:gen_server">gen_server(3)</seealso>,
+ where all interface functions and callback
+ functions are described in detail.</p>
+
+ <section>
+ <title>Client-Server Principles</title>
+ <p>The client-server model is characterized by a central server
+ and an arbitrary number of clients. The client-server model is
+ generally used for resource management operations, where several
+ different clients want to share a common resource. The server is
+ responsible for managing this resource.</p>
+ <marker id="clientserver"></marker>
+ <image file="../design_principles/clientserver.gif">
+ <icaption>Client-Server Model</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>Example</title>
+ <p>An example of a simple server written in plain Erlang was
+ given in <seealso marker="des_princ#ch1">Overview</seealso>.
+ The server can be re-implemented using <c>gen_server</c>,
+ resulting in this callback module:</p>
+ <marker id="ex"></marker>
+ <code type="none">
+-module(ch3).
+-behaviour(gen_server).
+
+-export([start_link/0]).
+-export([alloc/0, free/1]).
+-export([init/1, handle_call/3, handle_cast/2]).
+
+start_link() ->
+ gen_server:start_link({local, ch3}, ch3, [], []).
+
+alloc() ->
+ gen_server:call(ch3, alloc).
+
+free(Ch) ->
+ gen_server:cast(ch3, {free, Ch}).
+
+init(_Args) ->
+ {ok, channels()}.
+
+handle_call(alloc, _From, Chs) ->
+ {Ch, Chs2} = alloc(Chs),
+ {reply, Ch, Chs2}.
+
+handle_cast({free, Ch}, Chs) ->
+ Chs2 = free(Ch, Chs),
+ {noreply, Chs2}.</code>
+ <p>The code is explained in the next sections.</p>
+ </section>
+
+ <section>
+ <title>Starting a Gen_Server</title>
+ <p>In the example in the previous section, the gen_server is started
+ by calling <c>ch3:start_link()</c>:</p>
+ <code type="none">
+start_link() ->
+ gen_server:start_link({local, ch3}, ch3, [], []) => {ok, Pid}</code>
+ <p><c>start_link</c> calls the function
+ <c>gen_server:start_link/4</c>. This function spawns and links to
+ a new process, a gen_server.</p>
+ <list type="bulleted">
+ <item>
+ <p>The first argument <c>{local, ch3}</c> specifies the name. In
+ this case, the gen_server will be locally registered as
+ <c>ch3</c>.</p>
+ <p>If the name is omitted, the gen_server is not registered.
+ Instead its pid must be used. The name could also be given
+ as <c>{global, Name}</c>, in which case the gen_server is
+ registered using <c>global:register_name/2</c>.</p>
+ </item>
+ <item>
+ <p>The second argument, <c>ch3</c>, is the name of the callback
+ module, that is the module where the callback functions are
+ located.</p>
+ <p>In this case, the interface functions (<c>start_link</c>,
+ <c>alloc</c> and <c>free</c>) are located in the same module
+ as the callback functions (<c>init</c>, <c>handle_call</c> and
+ <c>handle_cast</c>). This is normally good programming
+ practice, to have the code corresponding to one process
+ contained in one module.</p>
+ </item>
+ <item>
+ <p>The third argument, [], is a term which is passed as-is to
+ the callback function <c>init</c>. Here, <c>init</c> does not
+ need any indata and ignores the argument.</p>
+ </item>
+ <item>
+ <p>The fourth argument, [], is a list of options. See
+ <c>gen_server(3)</c> for available options.</p>
+ </item>
+ </list>
+ <p>If name registration succeeds, the new gen_server process calls
+ the callback function <c>ch3:init([])</c>. <c>init</c> is expected
+ to return <c>{ok, State}</c>, where <c>State</c> is the internal
+ state of the gen_server. In this case, the state is the available
+ channels.</p>
+ <code type="none">
+init(_Args) ->
+ {ok, channels()}.</code>
+ <p>Note that <c>gen_server:start_link</c> is synchronous. It does
+ not return until the gen_server has been initialized and is ready
+ to receive requests.</p>
+ <p><c>gen_server:start_link</c> must be used if the gen_server is
+ part of a supervision tree, i.e. is started by a supervisor.
+ There is another function <c>gen_server:start</c> to start a
+ stand-alone gen_server, i.e. a gen_server which is not part of a
+ supervision tree.</p>
+ </section>
+
+ <section>
+ <title>Synchronous Requests - Call</title>
+ <p>The synchronous request <c>alloc()</c> is implemented using
+ <c>gen_server:call/2</c>:</p>
+ <code type="none">
+alloc() ->
+ gen_server:call(ch3, alloc).</code>
+ <p><c>ch3</c> is the name of the gen_server and must agree with
+ the name used to start it. <c>alloc</c> is the actual request.</p>
+ <p>The request is made into a message and sent to the gen_server.
+ When the request is received, the gen_server calls
+ <c>handle_call(Request, From, State)</c> which is expected to
+ return a tuple <c>{reply, Reply, State1}</c>. <c>Reply</c> is
+ the reply which should be sent back to the client, and
+ <c>State1</c> is a new value for the state of the gen_server.</p>
+ <code type="none">
+handle_call(alloc, _From, Chs) ->
+ {Ch, Chs2} = alloc(Chs),
+ {reply, Ch, Chs2}.</code>
+ <p>In this case, the reply is the allocated channel <c>Ch</c> and
+ the new state is the set of remaining available channels
+ <c>Chs2</c>.</p>
+ <p>Thus, the call <c>ch3:alloc()</c> returns the allocated channel
+ <c>Ch</c> and the gen_server then waits for new requests, now
+ with an updated list of available channels.</p>
+ </section>
+
+ <section>
+ <title>Asynchronous Requests - Cast</title>
+ <p>The asynchronous request <c>free(Ch)</c> is implemented using
+ <c>gen_server:cast/2</c>:</p>
+ <code type="none">
+free(Ch) ->
+ gen_server:cast(ch3, {free, Ch}).</code>
+ <p><c>ch3</c> is the name of the gen_server. <c>{free, Ch}</c> is
+ the actual request.</p>
+ <p>The request is made into a message and sent to the gen_server.
+ <c>cast</c>, and thus <c>free</c>, then returns <c>ok</c>.</p>
+ <p>When the request is received, the gen_server calls
+ <c>handle_cast(Request, State)</c> which is expected to
+ return a tuple <c>{noreply, State1}</c>. <c>State1</c> is a new
+ value for the state of the gen_server.</p>
+ <code type="none">
+handle_cast({free, Ch}, Chs) ->
+ Chs2 = free(Ch, Chs),
+ {noreply, Chs2}.</code>
+ <p>In this case, the new state is the updated list of available
+ channels <c>Chs2</c>. The gen_server is now ready for new
+ requests.</p>
+ </section>
+
+ <section>
+ <title>Stopping</title>
+
+ <section>
+ <title>In a Supervision Tree</title>
+ <p>If the gen_server is part of a supervision tree, no stop
+ function is needed. The gen_server will automatically be
+ terminated by its supervisor. Exactly how this is done is
+ defined by a <seealso marker="sup_princ#shutdown">shutdown strategy</seealso> set in the supervisor.</p>
+ <p>If it is necessary to clean up before termination, the shutdown
+ strategy must be a timeout value and the gen_server must be set
+ to trap exit signals in the <c>init</c> function. When ordered
+ to shutdown, the gen_server will then call the callback function
+ <c>terminate(shutdown, State)</c>:</p>
+ <code type="none">
+init(Args) ->
+ ...,
+ process_flag(trap_exit, true),
+ ...,
+ {ok, State}.
+
+...
+
+terminate(shutdown, State) ->
+ ..code for cleaning up here..
+ ok.</code>
+ </section>
+
+ <section>
+ <title>Stand-Alone Gen_Servers</title>
+ <p>If the gen_server is not part of a supervision tree, a stop
+ function may be useful, for example:</p>
+ <code type="none">
+...
+export([stop/0]).
+...
+
+stop() ->
+ gen_server:cast(ch3, stop).
+...
+
+handle_cast(stop, State) ->
+ {stop, normal, State};
+handle_cast({free, Ch}, State) ->
+ ....
+
+...
+
+terminate(normal, State) ->
+ ok.</code>
+ <p>The callback function handling the <c>stop</c> request returns
+ a tuple <c>{stop, normal, State1}</c>, where <c>normal</c>
+ specifies that it is a normal termination and <c>State1</c> is
+ a new value for the state of the gen_server. This will cause
+ the gen_server to call <c>terminate(normal,State1)</c> and then
+ terminate gracefully.</p>
+ </section>
+ </section>
+
+ <section>
+ <title>Handling Other Messages</title>
+ <p>If the gen_server should be able to receive other messages than
+ requests, the callback function <c>handle_info(Info, State)</c>
+ must be implemented to handle them. Examples of other messages
+ are exit messages, if the gen_server is linked to other processes
+ (than the supervisor) and trapping exit signals.</p>
+ <code type="none">
+handle_info({'EXIT', Pid, Reason}, State) ->
+ ..code to handle exits here..
+ {noreply, State1}.</code>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/inclappls.fig b/system/doc/design_principles/inclappls.fig
new file mode 100644
index 0000000000..03885c72d6
--- /dev/null
+++ b/system/doc/design_principles/inclappls.fig
@@ -0,0 +1,33 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2700 900 530 530 2700 900 3075 1275
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 750 2400 375 375 750 2400 975 2700
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1950 2400 375 375 1950 2400 2175 2700
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3150 2475 375 375 3150 2475 3375 2775
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 4425 2475 375 375 4425 2475 4650 2775
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 5700 2475 375 375 5700 2475 5925 2775
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3600 3600 375 375 3600 3600 3825 3900
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2625 3600 375 375 2625 3600 2850 3900
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 675 3600 375 375 675 3600 900 3900
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 975 2100 2250 1200
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2025 2025 2475 1425
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3000 2100 2850 1425
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3150 1275 4125 2250
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3225 1050 5400 2250
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 675 2775 675 3225
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3225 2850 3525 3225
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3075 2850 2700 3225
+4 0 -1 0 0 2 14 0.0000 4 195 1905 3525 975 Primary application \001
+4 0 -1 0 0 2 14 0.0000 4 195 1950 6525 2550 Included applications\001
+4 0 -1 0 0 2 14 0.0000 4 195 1950 6525 3675 Included applications\001
diff --git a/system/doc/design_principles/inclappls.gif b/system/doc/design_principles/inclappls.gif
new file mode 100644
index 0000000000..8b88d6d23e
--- /dev/null
+++ b/system/doc/design_principles/inclappls.gif
Binary files differ
diff --git a/system/doc/design_principles/inclappls.ps b/system/doc/design_principles/inclappls.ps
new file mode 100644
index 0000000000..239be1b3b3
--- /dev/null
+++ b/system/doc/design_principles/inclappls.ps
@@ -0,0 +1,808 @@
+%!PS-Adobe-3.0 EPSF-3.0
+%%Creator: (ImageMagick)
+%%Title: (./inclappls.tmp.eps)
+%%CreationDate: (Tue Jun 12 17:22:15 2001)
+%%BoundingBox: 0 20 377 197
+%%DocumentData: Clean7Bit
+%%LanguageLevel: 1
+%%Pages: 0
+%%EndComments
+
+%%BeginDefaults
+%%PageOrientation: Portrait
+%%EndDefaults
+
+%%BeginProlog
+%
+% Display a color image. The image is displayed in color on
+% Postscript viewers or printers that support color, otherwise
+% it is displayed as grayscale.
+%
+/buffer 512 string def
+/byte 1 string def
+/color_packet 3 string def
+/pixels 768 string def
+
+/DirectClassPacket
+{
+ %
+ % Get a DirectClass packet.
+ %
+ % Parameters:
+ % red.
+ % green.
+ % blue.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ compression 0 gt
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/DirectClassImage
+{
+ %
+ % Display a DirectClass image.
+ %
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { DirectClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayDirectClassPacket } image
+ } ifelse
+} bind def
+
+/GrayDirectClassPacket
+{
+ %
+ % Get a DirectClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % red
+ % green
+ % blue
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile color_packet readhexstring pop pop
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 gt
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/GrayPseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet; convert to grayscale.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ color_packet 0 get 0.299 mul
+ color_packet 1 get 0.587 mul add
+ color_packet 2 get 0.114 mul add
+ cvi
+ /gray_packet exch def
+ compression 0 gt
+ {
+ /number_pixels 1 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add def
+ } ifelse
+ 0 1 number_pixels 1 sub
+ {
+ pixels exch gray_packet put
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassPacket
+{
+ %
+ % Get a PseudoClass packet.
+ %
+ % Parameters:
+ % index: index into the colormap.
+ % length: number of pixels minus one of this color (optional).
+ %
+ currentfile byte readhexstring pop 0 get
+ /offset exch 3 mul def
+ /color_packet colormap offset 3 getinterval def
+ compression 0 gt
+ {
+ /number_pixels 3 def
+ }
+ {
+ currentfile byte readhexstring pop 0 get
+ /number_pixels exch 1 add 3 mul def
+ } ifelse
+ 0 3 number_pixels 1 sub
+ {
+ pixels exch color_packet putinterval
+ } for
+ pixels 0 number_pixels getinterval
+} bind def
+
+/PseudoClassImage
+{
+ %
+ % Display a PseudoClass image.
+ %
+ % Parameters:
+ % class: 0-PseudoClass or 1-Grayscale.
+ %
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ class 0 gt
+ {
+ currentfile buffer readline pop
+ token pop /depth exch def pop
+ /grays columns 8 add depth sub depth mul 8 idiv string def
+ columns rows depth
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { currentfile grays readhexstring pop } image
+ }
+ {
+ %
+ % Parameters:
+ % colors: number of colors in the colormap.
+ % colormap: red, green, blue color packets.
+ %
+ currentfile buffer readline pop
+ token pop /colors exch def pop
+ /colors colors 3 mul def
+ /colormap colors string def
+ currentfile colormap readhexstring pop pop
+ systemdict /colorimage known
+ {
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { PseudoClassPacket } false 3 colorimage
+ }
+ {
+ %
+ % No colorimage operator; convert to grayscale.
+ %
+ columns rows 8
+ [
+ columns 0 0
+ rows neg 0 rows
+ ]
+ { GrayPseudoClassPacket } image
+ } ifelse
+ } ifelse
+} bind def
+
+/DisplayImage
+{
+ %
+ % Display a DirectClass or PseudoClass image.
+ %
+ % Parameters:
+ % x & y translation.
+ % x & y scale.
+ % label pointsize.
+ % image label.
+ % image columns & rows.
+ % class: 0-DirectClass or 1-PseudoClass.
+ % compression: 0-RunlengthEncodedCompression or 1-NoCompression.
+ % hex color packets.
+ %
+ gsave
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ x y translate
+ currentfile buffer readline pop
+ token pop /x exch def
+ token pop /y exch def pop
+ currentfile buffer readline pop
+ token pop /pointsize exch def pop
+ /Helvetica findfont pointsize scalefont setfont
+ x y scale
+ currentfile buffer readline pop
+ token pop /columns exch def
+ token pop /rows exch def pop
+ currentfile buffer readline pop
+ token pop /class exch def pop
+ currentfile buffer readline pop
+ token pop /compression exch def pop
+ class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
+ grestore
+} bind def
+%%EndProlog
+%%Page: 1 1
+%%PageBoundingBox: 0 20 377 197
+userdict begin
+%%BeginData:
+DisplayImage
+0 20
+377.000000 177.000000
+12
+566 266
+1
+1
+1
+1
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffff
+fffffffffffff000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffffff
+ffffffffff0fff0fffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffffffff
+fffffff8fffff1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffffffffff
+ffffe7fffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffffffffffff
+ff9fffffff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffffffe
+7fffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffffffdff
+fffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffffff3ffff
+fffffcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffcffffffffffffffffffffffffffffffffffffefffffff
+ffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffcffffffffffffffffffffffffffffffffffffdfffffffff
+ffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffcffffffffffffffffffffffffffffffffffffbfffffffffff
+dfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffcffffffffffffffffffffffffffffffffffff7fffffffffffef
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffcfffffffffffffffffffffffffffffffffffefffffffffffff7ff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffcfffffffffffffffffffffffffffffffffffdfffffffffffffbffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffcfffffffffffffffffffffffffffffffffffbfffffffffffffdffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffcfffffffffffffffffffffffffffffffffffbfffffffffffffdffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffcfffffffffffffffffffffffffffffffffff7fffffffffffffeffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffcffffffffffffffffffffffffffffffffffefffffffffffffff7fffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffcffffffffffffffffffffffffffffffffffefffffffffffffff7fffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffcffffffffffffffffffffffffffffffffffdfffffffffffffffbfffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffcffffffffffffffffffffffffffffffffffdfffffffffffffffbfffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fcffffffffffffffffffffffffffffffffffbfffffffffffffffdfffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc
+ffffffffffffffffffffffffffffffffffbfffffffffffffffdfffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcff
+ffffffffffffffffffffffffffffffff7fffffffffffffffefffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff
+ffffffffffffffffffffffffffffff7fffffffffffffffefffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffff
+ffffffffffffffffffffffffffff7fffffffffffffffefffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffff
+fffffffffffffffffffffffffefffffffffffffffff7ffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffff
+fffffffffffffffffffffffefffffffffffffffff7ffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffff
+fffffffffffffffffffffefffffffffffffffff7ffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffff
+fffffffffffffffffffefffffffffffffffff7ffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffff
+fffffffffffffffffdfffffffffffffffffbffff01fe7ffffffffffffffc4fffff3fffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffff
+fffffffffffffffdfffffffffffffffffbffff9cfe7ffffffffffffffe4ffffb3fffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffff
+fffffffffffffdfffffffffffffffffbffff9cfffffffffffffffffe7ffff3ffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffff
+fffffffffffdfffffffffffffffffbffff9c9062230c813f0c8c8e0f086038623fffffff
+fffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffff
+fffffffffdfffffffffffffffffbffff9cc871126649be6666664e433333313fffffffff
+fffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffff
+fffffffdfffffffffffffffffbffff81ce73326679be6666664e733333333fffffffffff
+fffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffff
+fffffdfffffffffffffffffbffff9fce7333867d7f8666664e7c3333333fffffffffffff
+fffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffffff
+fffdfffffffffffffffffbffff9fce7332667c7e6666664e733333333fffffffffffffff
+fffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffffffff
+fdfffffffffffffffffbffff9fce7332667c7e6626264e233233333fffffffffffffffff
+fffffffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffd
+fffffffffffffffffbffff0f842110103efe124e4c07109018611fffffffffffffffffff
+fffffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffdff
+fffffffffffffffbfffffffffffffffefffe7e7fffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffdffff
+fffffffffffffbfffffffffffffff2fffe7e7fffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffeffffff
+fffffffffff7fffffffffffffff1fffc3c3fffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffeffffffff
+fffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffeffffffffff
+fffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffcfffffffffffffffffffffffffffffffffeffffffffffff
+fffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffcffffffffffffffffffffffffffffffffff7fffffffffffff
+ffe9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffcffffffffffffffffffffffffffffffffff7fffffffffffffff
+ee7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffcffffffffffffffffffffffffffffffffff7fffffffffffffffef
+9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffcffffffffffffffffffffffffffffffffffbfffffffffffffffdfe7
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffcffffffffffffffffffffffffffffffffffbfffffffffffffffdffbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffcffffffffffffffffffffffffffffffffffdfffffffffffffffbffcffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffcffffffffffffffffffffffffffffffffffdfffffffffffffffbfff3fffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffcffffffffffffffffffffffffffffffffffefffffffffffffff7fffcfffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffcffffffffffffffffffffffffffffffffffefffffffffffffff7ffff3ffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffcffffffffffffffffffffffffffffffffffe7fffffffffffffefffffcffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffcffffffffffffffffffffffffffffffffff9bfffffffffffffdffffff7fffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fcffffffffffffffffffffffffffffffffff7bfffffffffffffdffffff9fffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc
+fffffffffffffffffffffffffffffffffefdfffffffffffffbffffffe7ffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcff
+fffffffffffffffffffffffffffffff9fefffffffffffff7fffffff9ffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff
+fffffffffffffffffffffffffffff7ff7fffffffffffeefffffffe7fffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffff
+ffffffffffffffffffffffffffcfffbfffffffffffdf7fffffffbfffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffff
+ffffffffffffffffffffffffbfffdfffffffffffbfbfffffffcfffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffff
+fffffffffffffffffffffe7fffefffffffffff7fdffffffff3ffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffff
+fffffffffffffffffffdfffff3fffffffffcffeffffffffcffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffff
+fffffffffffffffffbfffffdfffffffffbfff7ffffffff3fffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffff
+ffffffffffffffe7fffffe7fffffffe7fffbffffffffdfffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffff
+ffffffffffffdfffffff9fffffff9ffffdffffffffe7ffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffff
+ffffffffff3fffffffe7fffffe7ffffefffffffff9ffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffff
+fffffffefffffffff8fffff1ffffff7ffffffffe7fffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffff
+fffffdffffffffdf0fff0fffffffbfffffffff9fffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffff
+fff3ffffffffbff000efffffffdfffffffffe7ffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffff
+efffffffffbfffffefffffffeffffffffffbffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffff9f
+ffffffff7ffffff7fffffff7fffffffffcffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffffff7fff
+fffffefffffff7fffffffbffffffffff3fffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffcffffff
+fffdfffffff7fffffffdffffffffffcfffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffffbffffffff
+fdfffffff7fffffffefffffffffff3ffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffcfffffffffffffffffffffffffff7fffffffffb
+fffffffbffffffff7ffffffffffdffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffcffffffffffffffffffffffffffcffffffffff7ff
+fffffbffffffffbffffffffffe7fffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffcffffffffffffffffffffffffffbfffffffffefffff
+fffbffffffffdfffffffffff9fffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffcfffffffffffffffffffffffffe7fffffffffefffffff
+fbffffffffefffffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffcfffffffffffffffffffffffffdffffffffffdffffffffb
+fffffffff7fffffffffff9ffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffcfffffffffffffffffffffffffbffffffffffbffffffffdff
+fffffffbfffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffcffffffffffffffffffffffffe7ffffffffff7ffffffffdffff
+fffffdffffffffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffcffffffffffffffffffffffffdfffffffffff7ffffffffdffffff
+fffeffffffffffffcfffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffcffffffffffffffffffffffff3ffffffffffefffffffffdffffffff
+ff7ffffffffffff3ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffcfffffffffffffffffffffffefffffffffffdfffffffffeffffffffff
+bffffffffffffcffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffcfffffffffffffffffffffff9fffffffffffbfffffffffeffffffffffdf
+ffffffffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffcfffffffffffffffffffffff7fffffffffffbfffffffffeffffffffffefff
+ffffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffcffffffffffffffffffffffeffffffffffff7fffffffffefffffffffff7ffff
+ffffffffe7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffcffffffffffffffffffffff9fffffffffffeffffffffffefffffffffffbffffff
+fffffff9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffcffffffffffffffffffffff7fffffffffffdfffffffffff7ffffffffffdffffffff
+fffffe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffcfffffffffffffffffffffcffffffffffffdfffffffffff7ffffffffffeffffffffff
+ffff9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fcfffffffffffffffffffffbffffffffffffbfffffffffff7fffffffffff7fffffffffff
+ffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc
+fffffffffffffffffffff7ffffffffffff7fffffffffff7fffffffffffbfffffffffffff
+f3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcff
+ffffffffffffffffffcffffffffffffeffffffffffffbfffffffffffdffffffffffffffc
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff
+ffffffffffffffffbffffffffffffeffffffffffffbfffffffffffefffffffffffffff3f
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffff
+fffffffffffffe7ffffffffffffdffffffffffffbffffffffffff7ffffffffffffffcfff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffff
+fffffffffffdfffffffffffffbffffffffffffbffffffffffffbfffffffffffffff7ffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffff
+fffffffff3fffffffffffff7ffffffffffffbffffffffffffdfffffffffffffff9ffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffff
+ffffffeffffffffffffff7ffffffffffffdffffffffffffefffffffffffffffe7fffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffff
+ffffdfffffffffffffefffffffffffffdfffffffffffff7fffffffffffffff9fffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffff
+ff3fffffffffffffdfffffffffffffdfffffffffffffbfffffffffffffffe7ffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffcfffffffffffffffffe
+ffffffffffffffbfffffffffffffdfffffffffffffdffffffffffffffff9ffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffcfffffffffffffffff9ff
+ffffffffffffbfffffffffffffefffffffffffffeffffffffffffffffeffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffcfffffffffffffffff7ffff
+ffffffffff7fffffffffffffeffffffffffffff7ffffffffffffffff3fffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffefffffff
+fffffffeffffffffffffffeffffffffffffffbffffffffffffffffcfffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffff9fffffffff
+fffffdffffffffffffffeffffffffffffffdfffffffffffffffff3ffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffcffffffffffffffff7fffffffffff
+fffdffffffffffffffeffffffffffffffefffffffffffffffffcffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffcfffffffffffffffcffffffffffffff
+fbfffffffffffffff7ffffffffffffff7fffffffffffffffff7fffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffcffffffffe00ffffbffffffffffffe007
+fffffffffffffff7ffffffffffffffbfffffffffffffffff9fffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffcfffffffe1ff0ffe7fffffffffffe1ff0ff
+fffffffffffff7ffffffffffffffdfffffffffffffffffe7ffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffcfffffff9ffff3fdffffffffffff9ffff3fff
+fffffffffff7ffffffffffffffeffffffffffffffffff9ffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffcffffffe7ffffcfbfffffffffffe7ffffcfffff
+fffffffffbfffffffffffffff7fffffffffffffffffe7fffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffcffffff9ffffff27fffffffffff9ffffff3ffffff
+fffffffbfffffffffffffffbffffffffffffffffffbfffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffcffffff7ffffffdffffffffffff7ffffffdffffffff
+fffffbe00ffffffffffffdffffff007fffffffffcffffffff803ffffffffffffffffffff
+fffffffffffffffffffffffffffcfffffefffffffefffffffffffefffffffeffffffffff
+fffe1ff0fffffffffffefffff0ff87fffffffff3ffffff87fc3fffffffffffffffffffff
+fffffffffffffffffffffffffcfffffdffffffff7ffffffffffdffffffff7fffffffffff
+f9ffff3fffffffffff7fffcffff9fffffffffcfffffe7fffcfffffffffffffffffffffff
+fffffffffffffffffffffffcfffffbffffffffbffffffffffbffffffffbfffffffffffe7
+ffffcfffffffffffbfff3ffffe7fffffffff3ffff9fffff3ffffffffffffffffffffffff
+fffffffffffffffffffffcfffff7ffffffffdffffffffff7ffffffffdfffffffffff9fff
+fff3ffffffffffdffcffffff9fffffffffcfffe7fffffcffffffffffffffffffffffffff
+fffffffffffffffffffcffffefffffffffefffffffffefffffffffefffffffffff7fffff
+fdffffffffffeffbffffffeffffffffff7ffdfffffff7fffffffffffffffffffffffffff
+fffffffffffffffffcffffdffffffffff7ffffffffdffffffffff7fffffffffefffffffe
+fffffffffff7f7fffffff7fffffffff9ffbfffffffbfffffffffffffffffffffffffffff
+fffffffffffffffcffffdffffffffff7ffffffffdffffffffff7fffffffffdffffffff7f
+fffffffffbeffffffffbfffffffffe7f7fffffffdfffffffffffffffffffffffffffffff
+fffffffffffffcffffbffffffffffbffffffffbffffffffffbfffffffffbffffffffbfff
+fffffffddffffffffdffffffffff9effffffffefffffffffffffffffffffffffffffffff
+fffffffffffcffffbffffffffffbffffffffbffffffffffbfffffffff7ffffffffdfffff
+fffffebffffffffeffffffffffe5fffffffff7ffffffffffffffffffffffffffffffffff
+fffffffffcffff7ffffffffffdffffffff7ffffffffffdffffffffefffffffffefffffff
+ffff7fffffffff7ffffffffffbfffffffffbffffffffffffffffffffffffffffffffffff
+fffffffcffff7ffffffffffdffffffff7ffffffffffdffffffffdffffffffff7ffffffff
+feffffffffffbffffffffff7fffffffffdffffffffffffffffffffffffffffffffffffff
+fffffcfffefffffffffffefffffffefffffffffffeffffffffdffffffffff7fffffffffe
+ffffffffffbffffffffff7fffffffffdffffffffffffffffffffffffffffffffffffffff
+fffcfffefffffffffffefffffffefffffffffffeffffffffbffffffffffbfffffffffdff
+ffffffffdfffffffffeffffffffffeffffffffffffffffffffffffffffffffffffffffff
+fcfffefffffffffffefffffffefffffffffffeffffffffbffffffffffbfffffffffdffff
+ffffffdfffffffffeffffffffffefffffffffffffffffffffffffffffffffffffffffffc
+fffefffffffffffefffffffefffffffffffeffffffff7ffffffffffdfffffffffbffffff
+ffffefffffffffdfffffffffff7ffffffffffffffffffffffffffffffffffffffffffcff
+fdffffffffffff7ffffffdffffffffffff7fffffff7ffffffffffdfffffffffbffffffff
+ffefffffffffdfffffffffff7ffffffffffffffffffffffffffffffffffffffffffcfffd
+ffffffffffff7ffffffdffffffffffff7ffffffefffffffffffefffffffff7ffffffffff
+f7ffffffffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffcfffdff
+ffffffffff7ffffffdffffffffffff7ffffffefffffffffffefffffffff7fffffffffff7
+ffffffffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffcfffdffff
+ffffffff7ffffffdffffffffffff7ffffffefffffffffffefffffffff7fffffffffff7ff
+ffffffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffcfffdffffff
+ffffff7ffffffdffffffffffff7ffffffefffffffffffefffffffff7fffffffffff7ffff
+ffffbfffffffffffbfffffff87ffe3ffc7ff1fffffff13ffffcffffffffcfffdffffffff
+ffff7ffffffdffffffffffff7ffffffdffffffffffff7fffffffeffffffffffffbffffff
+ff7fffffffffffdfffffffcffff3ffe7ff9fffffff93fffecffffffffcfffdffffffffff
+ff7ffffffdffffffffffff7ffffffdffffffffffff7fffffffeffffffffffffbffffffff
+7fffffffffffdfffffffcffff3ffe7ff9fffffff9ffffcfffffffffcfffdffffffffffff
+7ffffffdffffffffffff7ffffffdffffffffffff7fffffffeffffffffffffbffffffff7f
+ffffffffffdfffffffc88e1223270c9fc3232383c2180e188c3ffcfffdffffffffffff7f
+fffffdffffffffffff7ffffffdffffffffffff7fffffffeffffffffffffbffffffff7fff
+ffffffffdfffffffcc4c933246611f9999999390cccccc49bffcfffefffffffffffeffff
+fffefffffffffffefffffffdffffffffffff7fffffffeffffffffffffbffffffff7fffff
+ffffffdfffffffccccf33266619f999999939cccccccc8fffcfffefffffffffffeffffff
+fefffffffffffefffffffdffffffffffff7fffffffeffffffffffffbffffffff7fffffff
+ffffdfffffffccccf33266019fe19999939f0ccccccc3ffcfffefffffffffffefffffffe
+fffffffffffefffffffdffffffffffff7fffffffeffffffffffffbffffffff7fffffffff
+ffdfffffffccccf33266799f999999939ccccccccf3ffcfffefffffffffffefffffffeff
+fffffffffefffffffdffffffffffff7fffffffeffffffffffffbffffffff7fffffffffff
+dfffffffcccc532266719f9989899388cc8ccccbbffcffff7ffffffffffdffffffff7fff
+fffffffdfffffffdffffffffffff7fffffffeffffffffffffbffffffff7fffffffffffdf
+ffffff80462111130c4f84939301c4240618407ffcffff7ffffffffffdffffffff7fffff
+fffffdfffffffefffffffffffefffffffff7fffffffffff7ffffffffbfffffffffffbfff
+ffffffffffffffffffff9f9ffffffffffffffffcffffbffffffffffbffffffffbfffffff
+fffbfffffffefffffffffffefffffffff7fffffffffff7ffffffffbfffffffffffbfffff
+ffffffffffffffffff9f9ffffffffffffffffcffffbffffffffffbffffffffbfffffffff
+fbfffffffefffffffffffefffffffff7fffffffffff7ffffffffbfffffffffffbfffffff
+ffffffffffffffff0f0ffffffffffffffffcffffdffffffffff7ffffffffdffffffffff7
+fffffffefffffffffffefffffffff7fffffffffff7ffffffffbfffffffffffbfffffffff
+fffffffffffffffffffffffffffffffffcffffdffffffffff7ffffffffdffffffffff7ff
+ffffff7ffffffffffdfffffffffbffffffffffefffffffffdfffffffffff7fffffffffff
+fffffffffffffffffffffffffffffffcffffefffffffffefffffffffefffffffffefffff
+ffff7ffffffffffdfffffffffbffffffffffefffffffffdfffffffffff7fffffffffffff
+fffffffffffffffffffffffffffffcfffff7ffffffffdffffffffff7ffffffffdfffffff
+ffbffffffffffbfffffffffdffffffffffdfffffffffeffffffffffeffffffffffffffff
+fffffffffffffffffffffffffffcfffffbffffffffbffffffffffbffffffffbfffffffff
+bffffffffffbfffffffffdffffffffffdfffffffffeffffffffffeffffffffffffffffff
+fffffffffffffffffffffffffcfffffdffffffff7ffffffffffdffffffff7fffffffffdf
+fffffffff7fffffffffeffffffffffbffffffffff7fffffffffdffffffffffffffffffff
+fffffffffffffffffffffffcfffffefffffffefffffffffffefffffffeffffffffffdfff
+fffffff7fffffffffeffffffffffbffffffffff7fffffffffdffffffffffffffffffffff
+fffffffffffffffffffffcffffff7ffffffdffffffffffff7ffffffdffffffffffefffff
+ffffefffffffffff7fffffffff7ffffffffffbfffffffffbffffffffffffffffffffffff
+fffffffffffffffffffcffffff9ffffff3ffffffffffff9ffffff3fffffffffff7ffffff
+ffdfffffffffffbffffffffefffffffffffdfffffffff7ffffffffffffffffffffffffff
+fffffffffffffffffcffffffe7ffffcfffffffffffffe7ffffcffffffffffffbffffffff
+bfffffffffffdffffffffdfffffffffffeffffffffefffffffffffffffffffffffffffff
+fffffffffffffffcfffffff9ffff3ffffffffffffff9ffff3ffffffffffffdffffffff7f
+ffffffffffeffffffffbffffffffffff7fffffffdfffffffffffffffffffffffffffffff
+fffffffffffffcfffffffe1ff0fffffffffffffffe1ff0fffffffffffffefffffffeffff
+fffffffff7fffffff7ffffffffffffbfffffffbfffffffffffffffffffffffffffffffff
+fffffffffffcffffffffc00fffffffffffffffffe00fffffffffffffff7ffffffdffffff
+fffffffbffffffefffffffffffffdfffffff7fffffffffffffffffffffffffffffffffff
+fffffffffcffffffffdfffffffffffffffffffffffffffffffffffff9ffffff3ffffffff
+fffffcffffff9fffffffffffffe7fffffcffffffffffffffffffffffffffffffffffffff
+fffffffcffffffffdfffffffffffffffffffffffffffffffffffffe7ffffcfffffffffff
+ffff3ffffe7ffffffffffffff9fffff3ffffffffffffffffffffffffffffffffffffffff
+fffffcffffffffdffffffffffffffffffffffffffffffffffffff9ffff3fffffffffffff
+ffcffff9fffffffffffffffe7fffcfffffffffffffffffffffffffffffffffffffffffff
+fffcffffffffdffffffffffffffffffffffffffffffffffffffe1ff0ffffffffffffffff
+f0ff87ffffffffffffffff87fc3fffffffffffffffffffffffffffffffffffffffffffff
+fcffffffffdfffffffffffffffffffffffffffffffffffffffc007ffffffffffffffffff
+007ffffffffffffffffff803fffffffffffffffffffffffffffffffffffffffffffffffc
+ffffffffdfffffffffffffffffffffffffffffffffffffffbffbffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcff
+ffffffdfffffffffffffffffffffffffffffffffffffff7ffdffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff
+ffffdffffffffffffffffffffffffffffffffffffffefffdffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffff
+ffdffffffffffffffffffffffffffffffffffffffdfffeffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffff
+dffffffffffffffffffffffffffffffffffffffbffff7fffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffdf
+fffffffffffffffffffffffffffffffffffff7ffffbfffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffdfff
+ffffffffffffffffffffffffffffffffffefffffdfffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffdfffff
+ffffffffffffffffffffffffffffffffdfffffdfffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffdfffffff
+ffffffffffffffffffffffffffffffbfffffefffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffdfffffffff
+ffffffffffffffffffffffffffff7ffffff7ffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffdfffffffffff
+fffffffffffffffffffffffffefffffffbffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffcffffffffdfffffffffffff
+fffffffffffffffffffffffdfffffffdffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffcffffffffdfffffffffffffff
+fffffffffffffffffffffbfffffffdffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffcffffffffdfffffffffffffffff
+fffffffffffffffffff7fffffffeffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffcffffffffdfffffffffffffffffff
+ffffffffffffffffefffffffff7fffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffcffffffffdfffffffffffffffffffff
+ffffffffffffffdfffffffffbfffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffcffffffffdfffffffffffffffffffffff
+ffffffffffffbfffffffffdfffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffcffffffffdfffffffffffffffffffffffff
+ffffffffff7fffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffcffffffffdfffffffffffffffffffffffffff
+fffffffeffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffcffffffffdfffffffffffffffffffffffffffff
+fffffdfffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffcffffffffdfffffffffffffffffffffffffffffff
+fffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffcffffffffdfffffffffffffffffffffffffffffffff
+f7fffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffcffffffffdfffffffffffffffffffffffffffffffffef
+fffffffffffdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffcffffffffdfffffffffffffffffffffffffffffffffdfff
+fffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffcfffffffc01ffffffffffffffffffffffffffffff003fffff
+ffffffff003fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffcffffffc3fe1ffffffffffffffffffffffffffff0ff87ffffff
+fffff87fc3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffcffffff3fffe7ffffffffffffffffffffffffffcffff9ffffffff
+ffe7fffcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffcfffffcfffff9ffffffffffffffffffffffffff3ffffe7fffffffff
+9fffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffcfffff3fffffe7ffffffffffffffffffffffffcffffff9ffffffffe7f
+ffffcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffcffffefffffffbffffffffffffffffffffffffbffffffeffffffffdffff
+fff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffcffffdfffffffdffffffffffffffffffffffff7fffffff7fffffffbffffff
+fbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffcffffbfffffffefffffffffffffffffffffffeffffffffbfffffff7fffffffd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffcffff7ffffffff7ffffffffffffffffffffffdffffffffdffffffeffffffffeff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffcfffefffffffffbffffffffffffffffffffffbffffffffeffffffdfffffffff7fff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffcfffdfffffffffdffffffffffffffffffffff7fffffffff7fffffbfffffffffbfffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fcfffbfffffffffefffffffffffffffffffffeffffffffffbfffff7fffffffffdfffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc
+fffbfffffffffefffffffffffffffffffffeffffffffffbfffff7fffffffffdfffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcff
+f7ffffffffff7ffffffffffffffffffffdffffffffffdffffeffffffffffefffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfff7
+ffffffffff7ffffffffffffffffffffdffffffffffdffffeffffffffffefffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffefff
+ffffffffbffffffffffffffffffffbffffffffffeffffdfffffffffff7ffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffefffff
+ffffffbffffffffffffffffffffbffffffffffeffffdfffffffffff7ffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffdfffffff
+ffffdffffffffffffffffffff7fffffffffff7fffbfffffffffffbffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffdfffffffff
+ffdffffffffffffffffffff7fffffffffff7fffbfffffffffffbffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffdfffffffffff
+dffffffffffffffffffff7fffffffffff7fffbfffffffffffbffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffcffdfffffffffffdf
+fffffffffffffffffff7fffffffffff7fffbfffffffffffbffffffffffffffffffffffff
+ffffffffffffffffff87ffe3ffc7ff1fffffff13ffffcffffffffcffbfffffffffffefff
+ffffffffffffffffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffff
+ffffffffffffffffcffff3ffe7ff9fffffff93fffecffffffffcffbfffffffffffefffff
+ffffffffffffffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffffff
+ffffffffffffffcffff3ffe7ff9fffffff9ffffcfffffffffcffbfffffffffffefffffff
+ffffffffffffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffffffff
+ffffffffffffc88e1223270c9fc3232383c2180e188c3ffcffbfffffffffffefffffffff
+ffffffffffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffffffffff
+ffffffffffcc4c933246611f9999999390cccccc49bffcffbfffffffffffefffffffffff
+ffffffffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffffffffffff
+ffffffffccccf33266619f999999939cccccccc8fffcffbfffffffffffefffffffffffff
+ffffffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffffffffffffff
+ffffffccccf33266019fe19999939f0ccccccc3ffcffbfffffffffffefffffffffffffff
+ffffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffffffffffffffff
+ffffccccf33266799f999999939ccccccccf3ffcffbfffffffffffefffffffffffffffff
+ffeffffffffffffbfff7fffffffffffdffffffffffffffffffffffffffffffffffffffff
+ffcccc532266719f9989899388cc8ccccbbffcffbfffffffffffefffffffffffffffffff
+effffffffffffbfff7fffffffffffdffffffffffffffffffffffffffffffffffffffffff
+80462111130c4f84939301c4240618407ffcffdfffffffffffdffffffffffffffffffff7
+fffffffffff7fffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffffff9f9ffffffffffffffffcffdfffffffffffdffffffffffffffffffff7ff
+fffffffff7fffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffffff9f9ffffffffffffffffcffdfffffffffffdffffffffffffffffffff7ffff
+fffffff7fffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffffffff
+ffffffffff0f0ffffffffffffffffcffdfffffffffffdffffffffffffffffffff7ffffff
+fffff7fffbfffffffffffbffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffcffefffffffffffbffffffffffffffffffffbffffffff
+ffeffffdfffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffcffefffffffffffbffffffffffffffffffffbffffffffff
+effffdfffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffcfff7ffffffffff7ffffffffffffffffffffdffffffffffdf
+fffeffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffcfff7ffffffffff7ffffffffffffffffffffdffffffffffdfff
+feffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffcfffbfffffffffefffffffffffffffffffffeffffffffffbfffff
+7fffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffcfffbfffffffffefffffffffffffffffffffeffffffffffbfffff7f
+ffffffffdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffcfffdfffffffffdffffffffffffffffffffff7fffffffff7fffffbfff
+ffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffcfffefffffffffbffffffffffffffffffffffbffffffffeffffffdfffff
+ffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffcffff7ffffffff7ffffffffffffffffffffffdffffffffdffffffefffffff
+feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffcffffbfffffffefffffffffffffffffffffffeffffffffbfffffff7fffffffd
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffcffffdfffffffdffffffffffffffffffffffff7fffffff7fffffffbfffffffbff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffcffffefffffffbffffffffffffffffffffffffbffffffeffffffffdfffffff7ffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffcfffff3fffffe7ffffffffffffffffffffffffcffffff9ffffffffe7fffffcfffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fcfffffcfffff9ffffffffffffffffffffffffff3ffffe7fffffffff9fffff3fffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc
+ffffff3fffe7ffffffffffffffffffffffffffcffff9ffffffffffe7fffcffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcff
+ffffc3fe1ffffffffffffffffffffffffffff0ff87fffffffffff87fc3ffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffff
+fffc01ffffffffffffffffffffffffffffff007fffffffffffff803fffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffffcffffffffffffffffffffffffff
+ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+fffffffffffffffffffffffffffffffffffffffffffc
+%%EndData
+end
+%%PageTrailer
+%%Trailer
+%%BoundingBox: 0 20 377 197
+%%EOF
diff --git a/system/doc/design_principles/included_applications.xml b/system/doc/design_principles/included_applications.xml
new file mode 100644
index 0000000000..3adb27ea08
--- /dev/null
+++ b/system/doc/design_principles/included_applications.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Included Applications</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>included_applications.xml</file>
+ </header>
+
+ <section>
+ <title>Definition</title>
+ <p>An application can <em>include</em> other applications.
+ An <em>included application</em> has its own application directory
+ and <c>.app</c> file, but it is started as part of the supervisor
+ tree of another application.</p>
+ <p>An application can only be included by one other application.</p>
+ <p>An included application can include other applications.</p>
+ <p>An application which is not included by any other application is
+ called a <em>primary application</em>.</p>
+ <marker id="inclappls"></marker>
+ <image file="../design_principles/inclappls.gif">
+ <icaption>Primary Application and Included Applications.</icaption>
+ </image>
+ <p>The application controller will automatically load any included
+ applications when loading a primary application, but not start
+ them. Instead, the top supervisor of the included application
+ must be started by a supervisor in the including application.</p>
+ <p>This means that when running, an included application is in fact
+ part of the primary application and a process in an included
+ application will consider itself belonging to the primary
+ application.</p>
+ </section>
+
+ <section>
+ <title>Specifying Included Applications</title>
+ <p>Which applications to include is defined by
+ the <c>included_applications</c> key in the <c>.app</c> file.</p>
+ <pre>
+{application, prim_app,
+ [{description, "Tree application"},
+ {vsn, "1"},
+ {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
+ {registered, [prim_app_server]},
+ {included_applications, [incl_app]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {prim_app_cb,[]}},
+ {env, [{file, "/usr/local/log"}]}
+ ]}.</pre>
+ </section>
+
+ <section>
+ <title>Synchronizing Processes During Startup</title>
+ <p>The supervisor tree of an included application is started as
+ part of the supervisor tree of the including application.
+ If there is a need for synchronization between processes in
+ the including and included applications, this can be achieved
+ by using <em>start phases</em>.</p>
+ <p>Start phases are defined by the <c>start_phases</c> key in
+ the <c>.app</c> file as a list of tuples <c>{Phase,PhaseArgs}</c>,
+ where <c>Phase</c> is an atom and <c>PhaseArgs</c> is a term.
+ Also, the value of the <c>mod</c> key of the including application
+ must be set to <c>{application_starter,[Module,StartArgs]}</c>,
+ where <c>Module</c> as usual is the application callback module
+ and <c>StartArgs</c> a term provided as argument to the callback
+ function <c>Module:start/2</c>.</p>
+ <code type="none">
+{application, prim_app,
+ [{description, "Tree application"},
+ {vsn, "1"},
+ {modules, [prim_app_cb, prim_app_sup, prim_app_server]},
+ {registered, [prim_app_server]},
+ {included_applications, [incl_app]},
+ {start_phases, [{init,[]}, {go,[]}]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {application_starter,[prim_app_cb,[]]}},
+ {env, [{file, "/usr/local/log"}]}
+ ]}.
+
+{application, incl_app,
+ [{description, "Included application"},
+ {vsn, "1"},
+ {modules, [incl_app_cb, incl_app_sup, incl_app_server]},
+ {registered, []},
+ {start_phases, [{go,[]}]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {incl_app_cb,[]}}
+ ]}.</code>
+ <p>When starting a primary application with included applications,
+ the primary application is started the normal way:
+ The application controller creates an application master for
+ the application, and the application master calls
+ <c>Module:start(normal, StartArgs)</c> to start the top
+ supervisor.</p>
+ <p>Then, for the primary application and each included application
+ in top-down, left-to-right order, the application master calls
+ <c>Module:start_phase(Phase, Type, PhaseArgs)</c> for each phase
+ defined for for the primary application, in that order.
+ Note that if a phase is not defined for an included application,
+ the function is not called for this phase and application.</p>
+ <p>The following requirements apply to the <c>.app</c> file for
+ an included application:</p>
+ <list type="bulleted">
+ <item>The <c>{mod, {Module,StartArgs}}</c> option must be
+ included. This option is used to find the callback module
+ <c>Module</c> of the application. <c>StartArgs</c> is ignored,
+ as <c>Module:start/2</c> is called only for the primary
+ application.</item>
+ <item>If the included application itself contains included
+ applications, instead the option
+ <c>{mod, {application_starter, [Module,StartArgs]}}</c> must be
+ included.</item>
+ <item>The <c>{start_phases, [{Phase,PhaseArgs}]}</c> option must
+ be included, and the set of specified phases must be a subset
+ of the set of phases specified for the primary application.</item>
+ </list>
+ <p>When starting <c>prim_app</c> as defined above, the application
+ controller will call the following callback functions, before
+ <c>application:start(prim_app)</c> returns a value:</p>
+ <code type="none">
+application:start(prim_app)
+ => prim_app_cb:start(normal, [])
+ => prim_app_cb:start_phase(init, normal, [])
+ => prim_app_cb:start_phase(go, normal, [])
+ => incl_app_cb:start_phase(go, normal, [])
+ok</code>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/make.dep b/system/doc/design_principles/make.dep
new file mode 100644
index 0000000000..05dd2333fb
--- /dev/null
+++ b/system/doc/design_principles/make.dep
@@ -0,0 +1,31 @@
+# ----------------------------------------------------
+# >>>> Do not edit this file <<<<
+# This file was automaticly generated by
+# /home/gandalf/otp/bin/docdepend
+# ----------------------------------------------------
+
+
+# ----------------------------------------------------
+# TeX files that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: applications.tex appup_cookbook.tex book.tex \
+ des_princ.tex distributed_applications.tex \
+ events.tex fsm.tex gen_server_concepts.tex \
+ included_applications.tex part.tex release_handling.tex \
+ release_structure.tex spec_proc.tex sup_princ.tex
+
+# ----------------------------------------------------
+# Pictures that the DVI file depend on
+# ----------------------------------------------------
+
+book.dvi: sup6.ps
+
+book.dvi: dist1.ps dist2.ps dist3.ps dist4.ps dist5.ps
+
+book.dvi: clientserver.ps
+
+book.dvi: inclappls.ps
+
+book.dvi: sup4.ps sup5.ps
+
diff --git a/system/doc/design_principles/note.gif b/system/doc/design_principles/note.gif
new file mode 100644
index 0000000000..6fffe30419
--- /dev/null
+++ b/system/doc/design_principles/note.gif
Binary files differ
diff --git a/system/doc/design_principles/part.xml b/system/doc/design_principles/part.xml
new file mode 100644
index 0000000000..d40b7cb23e
--- /dev/null
+++ b/system/doc/design_principles/part.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE part SYSTEM "part.dtd">
+
+<part xmlns:xi="http://www.w3.org/2001/XInclude">
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>OTP Design Principles</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ </header>
+ <xi:include href="des_princ.xml"/>
+ <xi:include href="gen_server_concepts.xml"/>
+ <xi:include href="fsm.xml"/>
+ <xi:include href="events.xml"/>
+ <xi:include href="sup_princ.xml"/>
+ <xi:include href="spec_proc.xml"/>
+ <xi:include href="applications.xml"/>
+ <xi:include href="included_applications.xml"/>
+ <xi:include href="distributed_applications.xml"/>
+ <xi:include href="release_structure.xml"/>
+ <xi:include href="release_handling.xml"/>
+ <xi:include href="appup_cookbook.xml"/>
+</part>
+
diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml
new file mode 100644
index 0000000000..1d62c242c0
--- /dev/null
+++ b/system/doc/design_principles/release_handling.xml
@@ -0,0 +1,667 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Release Handling</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>release_handling.xml</file>
+ </header>
+
+ <section>
+ <title>Release Handling Principles</title>
+ <p>An important feature of the Erlang programming language is
+ the ability to change module code in run-time, <em>code replacement</em>, as described in <em>Erlang Reference Manual</em>.</p>
+ <p>Based on this feature, the OTP application SASL provides a
+ framework for upgrading and downgrading between different
+ versions of an entire release in run-time. This is what we call
+ <em>release handling</em>.</p>
+ <p>The framework consists of off-line support (<c>systools</c>) for
+ generating scripts and building release packages, and on-line
+ support (<c>release_handler</c>) for unpacking and installing
+ release packages.</p>
+ <p>Note that the minimal system based on Erlang/OTP, enabling
+ release handling, thus consists of Kernel, STDLIB and SASL.</p>
+ <list type="ordered">
+ <item>
+ <p>A release is created as described in the previous chapter
+ <seealso marker="release_structure">Releases</seealso>.
+ The release is transferred to and installed at target
+ environment. Refer to <em>System Principles</em> for
+ information of how to install the first target system.</p>
+ </item>
+ <item>
+ <p>Modifications, for example error corrections, are made to
+ the code in the development environment.</p>
+ </item>
+ <item>
+ <p>At some point it is time to make a new version of release.
+ The relevant <c>.app</c> files are updated and a new
+ <c>.rel</c> file is written.</p>
+ </item>
+ <item>
+ <p>For each modified application, an
+ <seealso marker="#appup">application upgrade file</seealso>,
+ <c>.appup</c>, is created. In this file, it is described how
+ to upgrade and/or downgrade between the old and new version of
+ the application.</p>
+ </item>
+ <item>
+ <p>Based on the <c>.appup</c> files, a
+ <seealso marker="#relup">release upgrade file</seealso> called
+ <c>relup</c>, is created. This file describes how to upgrade
+ and/or downgrade between the old and new version of
+ the entire release.</p>
+ </item>
+ <item>
+ <p>A new release package is made and transferred to
+ the target system.</p>
+ </item>
+ <item>
+ <p>The new release package is unpacked using the release
+ handler.</p>
+ </item>
+ <item>
+ <p>The new version of the release is installed, also using
+ the release handler. This is done by evaluating
+ the instructions in <c>relup</c>. Modules may be added,
+ deleted or re-loaded, applications may be started, stopped or
+ re-started etc. In some cases, it is even necessary to restart
+ the entire emulator.</p>
+ <p>If the installation fails, the system may be rebooted.
+ The old release version is then automatically used.</p>
+ </item>
+ <item>
+ <p>If the installation succeeds, the new version is made
+ the default version, which should now be used in case of a
+ system reboot.</p>
+ </item>
+ </list>
+ <p>The next chapter, <seealso marker="appup_cookbook">Appup Cookbook</seealso>, contains examples of <c>.appup</c> files
+ for typical cases of upgrades/downgrades that are normally easy
+ to handle in run-time. However, there are a many aspects that can
+ make release handling complicated. To name a few examples:</p>
+ <list type="bulleted">
+ <item>
+ <p>Complicated or circular dependencies can make it difficult
+ or even impossible to decide in which order things must be
+ done without risking run-time errors during an upgrade or
+ downgrade. Dependencies may be:</p>
+ <list type="bulleted">
+ <item>between nodes,</item>
+ <item>between processes, and</item>
+ <item>between modules.</item>
+ </list>
+ </item>
+ <item>
+ <p>During release handling, non-affected processes continue
+ normal execution. This may lead to timeouts or other problems.
+ For example, new processes created in the time window between
+ suspending processes using a certain module and loading a new
+ version of this module, may execute old code.</p>
+ </item>
+ </list>
+ <p>It is therefore recommended that code is changed in as small
+ steps as possible, and always kept backwards compatible.</p>
+ </section>
+
+ <section>
+ <marker id="req"></marker>
+ <title>Requirements</title>
+ <p>For release handling to work properly, the runtime system needs
+ to have knowledge about which release it is currently running. It
+ must also be able to change (in run-time) which boot script and
+ system configuration file should be used if the system is
+ rebooted, for example by <c>heart</c> after a failure.
+ Therefore, Erlang must be started as an embedded system, see
+ <em>Embedded System</em> for information on how to do this.</p>
+ <p>For system reboots to work properly, it is also required that
+ the system is started with heart beat monitoring, see
+ <c>erl(1)</c> and <c>heart(3)</c>.</p>
+ <p>Other requirements:</p>
+ <list type="bulleted">
+ <item>
+ <p>The boot script included in a release package must be
+ generated from the same <c>.rel</c> file as the release
+ package itself.</p>
+ <p>Information about applications are fetched from the script
+ when an upgrade or downgrade is performed.</p>
+ </item>
+ <item>
+ <p>The system must be configured using one and only one system
+ configuration file, called <c>sys.config</c>.</p>
+ <p>If found, this file is automatically included when a release
+ package is created.</p>
+ </item>
+ <item>
+ <p>All versions of a release, except the first one, must
+ contain a <c>relup</c> file.</p>
+ <p>If found, this file is automatically included when a release
+ package is created.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Distributed Systems</title>
+ <p>If the system consists of several Erlang nodes, each node may use
+ its own version of the release. The release handler is a locally
+ registered process and must be called at each node where an
+ upgrade or downgrade is required. There is a release handling
+ instruction that can be used to synchronize the release handler
+ processes at a number of nodes: <c>sync_nodes</c>. See
+ <c>appup(4)</c>.</p>
+ </section>
+
+ <section>
+ <marker id="instr"></marker>
+ <title>Release Handling Instructions</title>
+ <p>OTP supports a set of <em>release handling instructions</em>
+ that is used when creating <c>.appup</c> files. The release
+ handler understands a subset of these, the <em>low-level</em>
+ instructions. To make it easier for the user, there are also a
+ number of <em>high-level</em> instructions, which are translated
+ to low-level instructions by <c>systools:make_relup</c>.</p>
+ <p>Here, some of the most frequently used instructions are
+ described. The complete list of instructions is found in
+ <c>appup(4)</c>.</p>
+ <p>First, some definitions:</p>
+ <taglist>
+ <tag><em>Residence module</em></tag>
+ <item>
+ <p>The module where a process has its tail-recursive loop
+ function(s). If the tail-recursive loop functions are
+ implemented in several modules, all those modules are residence
+ modules for the process.</p>
+ </item>
+ <tag><em>Functional module</em></tag>
+ <item>
+ <p>A module which is not a residence module for any process.</p>
+ </item>
+ </taglist>
+ <p>Note that for a process implemented using an OTP behaviour,
+ the behaviour module is the residence module for that process.
+ The callback module is a functional module.</p>
+
+ <section>
+ <title>load_module</title>
+ <p>If a simple extension has been made to a functional module, it
+ is sufficient to simply load the new version of the module into
+ the system, and remove the old version. This is called
+ <em>simple code replacement</em> and for this the following
+ instruction is used:</p>
+ <code type="none">
+{load_module, Module}</code>
+ </section>
+
+ <section>
+ <title>update</title>
+ <p>If a more complex change has been made, for example a change
+ to the format of the internal state of a gen_server, simple code
+ replacement is not sufficient. Instead it is necessary to
+ suspend the processes using the module (to avoid that they try
+ to handle any requests before the code replacement is
+ completed), ask them to transform the internal state format and
+ switch to the new version of the module, remove the old version
+ and last, resume the processes. This is called <em>synchronized code replacement</em> and for this the following instructions
+ are used:</p>
+ <code type="none">
+{update, Module, {advanced, Extra}}
+{update, Module, supervisor}</code>
+ <p><c>update</c> with argument <c>{advanced,Extra}</c> is used
+ when changing the internal state of a behaviour as described
+ above. It will cause behaviour processes to call the callback
+ function <c>code_change</c>, passing the term <c>Extra</c> and
+ some other information as arguments. See the man pages for
+ the respective behaviours and
+ <seealso marker="appup_cookbook#int_state">Appup Cookbook</seealso>.</p>
+ <p><c>update</c> with argument <c>supervisor</c> is used when
+ changing the start specification of a supervisor. See
+ <seealso marker="appup_cookbook#sup">Appup Cookbook</seealso>.</p>
+ <p>The release handler finds the processes <em>using</em> a module
+ to update by traversing the supervision tree of each running
+ application and checking all the child specifications:</p>
+ <code type="none">
+{Id, StartFunc, Restart, Shutdown, Type, Modules}</code>
+ <p>A process is using a module if the name is listed in
+ <c>Modules</c> in the child specification for the process.</p>
+ <p>If <c>Modules=dynamic</c>, which is the case for event
+ managers, the event manager process informs the release handler
+ about the list of currently installed event handlers (gen_fsm)
+ and it is checked if the module name is in this list instead.</p>
+ <p>The release handler suspends, asks for code change, and
+ resumes processes by calling the functions
+ <c>sys:suspend/1,2</c>, <c>sys:change_code/4,5</c> and
+ <c>sys:resume/1,2</c> respectively.</p>
+ </section>
+
+ <section>
+ <title>add_module and delete_module</title>
+ <p>If a new module is introduced, the following instruction is
+ used:</p>
+ <code type="none">
+{add_module, Module}</code>
+ <p>The instruction loads the module and is absolutely necessary
+ when running Erlang in embedded mode. It is not strictly
+ required when running Erlang in interactive (default) mode,
+ since the code server automatically searches for and loads
+ unloaded modules.</p>
+ <p>The opposite of <c>add_module</c> is <c>delete_module</c> which
+ unloads a module:</p>
+ <code type="none">
+{delete_module, Module}</code>
+ <p>Note that any process, in any application, with <c>Module</c>
+ as residence module, is killed when the instruction is
+ evaluated. The user should therefore ensure that all such
+ processes are terminated before deleting the module, to avoid
+ a possible situation with failing supervisor restarts.</p>
+ </section>
+
+ <section>
+ <title>Application Instructions</title>
+ <p>Instruction for adding an application:</p>
+ <code type="none">
+{add_application, Application}</code>
+ <p>Adding an application means that the modules defined by
+ the <c>modules</c> key in the <c>.app</c> file are loaded using
+ a number of <c>add_module</c> instructions, then the application
+ is started.</p>
+ <p>Instruction for removing an application:</p>
+ <code type="none">
+{remove_application, Application}</code>
+ <p>Removing an application means that the application is stopped,
+ the modules are unloaded using a number of <c>delete_module</c>
+ instructions and then the application specification is unloaded
+ from the application controller.</p>
+ <p>Instruction for removing an application:</p>
+ <code type="none">
+{restart_application, Application}</code>
+ <p>Restarting an application means that the application is stopped
+ and then started again similar to using the instructions
+ <c>remove_application</c> and <c>add_application</c> in
+ sequence.</p>
+ </section>
+
+ <section>
+ <title>apply (low-level)</title>
+ <p>To call an arbitrary function from the release handler,
+ the following instruction is used:</p>
+ <code type="none">
+{apply, {M, F, A}}</code>
+ <p>The release handler will evalute <c>apply(M, F, A)</c>.</p>
+ </section>
+
+ <section>
+ <title>restart_new_emulator (low-level)</title>
+ <p>This instruction is used when changing to a new emulator
+ version, or if a system reboot is needed for some other reason.
+ Requires that the system is started with heart beat
+ monitoring, see <c>erl(1)</c> and <c>heart(3)</c>.</p>
+ <p>When the release handler encounters the instruction, it shuts
+ down the current emulator by calling <c>init:reboot()</c>, see
+ <c>init(3)</c>. All processes are terminated gracefully and
+ the system can then be rebooted by the heart program, using
+ the new release version. This new version must still be made
+ permanent when the new emulator is up and running. Otherwise,
+ the old version is used in case of a new system reboot.</p>
+ <p>On UNIX, the release handler tells the heart program which
+ command to use to reboot the system. Note that the environment
+ variable <c>HEART_COMMAND</c>, normally used by the heart
+ program, in this case is ignored. The command instead defaults
+ to <c>$ROOT/bin/start</c>. Another command can be set
+ by using the SASL configuration parameter <c>start_prg</c>, see
+ <c>sasl(6)</c>.</p>
+ </section>
+ </section>
+
+ <section>
+ <marker id="appup"></marker>
+ <title>Application Upgrade File</title>
+ <p>To define how to upgrade/downgrade between the current version
+ and previous versions of an application, we create an
+ <em>application upgrade file</em>, or in short <c>.appup</c> file.
+ The file should be called <c>Application.appup</c>, where
+ <c>Application</c> is the name of the application:</p>
+ <code type="none">
+{Vsn,
+ [{UpFromVsn1, InstructionsU1},
+ ...,
+ {UpFromVsnK, InstructionsUK}],
+ [{DownToVsn1, InstructionsD1},
+ ...,
+ {DownToVsnK, InstructionsDK}]}.</code>
+ <p><c>Vsn</c>, a string, is the current version of the application,
+ as defined in the <c>.app</c> file. Each <c>UpFromVsn</c>
+ is a previous version of the application to upgrade from, and each
+ <c>DownToVsn</c> is a previous version of the application to
+ downgrade to. Each <c>Instructions</c> is a list of release
+ handling instructions.</p>
+ <p>The syntax and contents of the <c>appup</c> file are described
+ in detail in <c>appup(4)</c>.</p>
+ <p>In the chapter <seealso marker="appup_cookbook">Appup Cookbook</seealso>, examples of <c>.appup</c> files for typical
+ upgrade/downgrade cases are given.</p>
+ <p>Example: Consider the release <c>ch_rel-1</c> from
+ the <seealso marker="release_structure#ch_rel">Releases</seealso>
+ chapter. Assume we want to add a function <c>available/0</c> to
+ the server <c>ch3</c> which returns the number of available
+ channels:</p>
+ <p>(Hint: When trying out the example, make the changes in a copy of
+ the original directory, so that the first versions are still
+ available.)</p>
+ <code type="none">
+-module(ch3).
+-behaviour(gen_server).
+
+-export([start_link/0]).
+-export([alloc/0, free/1]).
+-export([available/0]).
+-export([init/1, handle_call/3, handle_cast/2]).
+
+start_link() ->
+ gen_server:start_link({local, ch3}, ch3, [], []).
+
+alloc() ->
+ gen_server:call(ch3, alloc).
+
+free(Ch) ->
+ gen_server:cast(ch3, {free, Ch}).
+
+available() ->
+ gen_server:call(ch3, available).
+
+init(_Args) ->
+ {ok, channels()}.
+
+handle_call(alloc, _From, Chs) ->
+ {Ch, Chs2} = alloc(Chs),
+ {reply, Ch, Chs2};
+handle_call(available, _From, Chs) ->
+ N = available(Chs),
+ {reply, N, Chs}.
+
+handle_cast({free, Ch}, Chs) ->
+ Chs2 = free(Ch, Chs),
+ {noreply, Chs2}.</code>
+ <p>A new version of the <c>ch_app.app</c> file must now be created,
+ where the version is updated:</p>
+ <code type="none">
+{application, ch_app,
+ [{description, "Channel allocator"},
+ {vsn, "2"},
+ {modules, [ch_app, ch_sup, ch3]},
+ {registered, [ch3]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {ch_app,[]}}
+ ]}.</code>
+ <p>To upgrade <c>ch_app</c> from <c>"1"</c> to <c>"2"</c> (and
+ to downgrade from <c>"2"</c> to <c>"1"</c>), we simply need to
+ load the new (old) version of the <c>ch3</c> callback module.
+ We create the application upgrade file <c>ch_app.appup</c> in
+ the <c>ebin</c> directory:</p>
+ <code type="none">
+{"2",
+ [{"1", [{load_module, ch3}]}],
+ [{"1", [{load_module, ch3}]}]
+}.</code>
+ </section>
+
+ <section>
+ <marker id="relup"></marker>
+ <title>Release Upgrade File</title>
+ <p>To define how to upgrade/downgrade between the new version and
+ previous versions of a release, we create a <em>release upgrade file</em>, or in short <c>relup</c> file.</p>
+ <p>This file does not need to be created manually, it can be
+ generated by <c>systools:make_relup/3,4</c>. The relevant versions
+ of the <c>.rel</c> file, <c>.app</c> files and <c>.appup</c> files
+ are used as input. It is deducted which applications should be
+ added and deleted, and which applications that need to be upgraded
+ and/or downgraded. The instructions for this is fetched from
+ the <c>.appup</c> files and transformed into a single list of
+ low-level instructions in the right order.</p>
+ <p>If the <c>relup</c> file is relatively simple, it can be created
+ manually. Remember that it should only contain low-level
+ instructions.</p>
+ <p>The syntax and contents of the release upgrade file are
+ described in detail in <c>relup(4)</c>.</p>
+ <p>Example, continued from the previous section. We have a new
+ version "2" of <c>ch_app</c> and an <c>.appup</c> file. We also
+ need a new version of the <c>.rel</c> file. This time the file is
+ called <c>ch_rel-2.rel</c> and the release version string is
+ changed changed from "A" to "B":</p>
+ <code type="none">
+{release,
+ {"ch_rel", "B"},
+ {erts, "5.3"},
+ [{kernel, "2.9"},
+ {stdlib, "1.12"},
+ {sasl, "1.10"},
+ {ch_app, "2"}]
+}.</code>
+ <p>Now the <c>relup</c> file can be generated:</p>
+ <pre>
+1> <input>systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"]).</input>
+ok</pre>
+ <p>This will generate a <c>relup</c> file with instructions for
+ how to upgrade from version "A" ("ch_rel-1") to version "B"
+ ("ch_rel-2") and how to downgrade from version "B" to version "A".</p>
+ <p>Note that both the old and new versions of the <c>.app</c> and
+ <c>.rel</c> files must be in the code path, as well as
+ the <c>.appup</c> and (new) <c>.beam</c> files. It is possible
+ to extend the code path by using the option <c>path</c>:</p>
+ <pre>
+1> <input>systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"],</input>
+<input>[{path,["../ch_rel-1",</input>
+<input>"../ch_rel-1/lib/ch_app-1/ebin"]}]).</input>
+ok</pre>
+ </section>
+
+ <section>
+ <marker id="rel_handler"></marker>
+ <title>Installing a Release</title>
+ <p>When we have made a new version of a release, a release package
+ can be created with this new version and transferred to the target
+ environment.</p>
+ <p>To install the new version of the release in run-time,
+ the <em>release handler</em> is used. This is a process belonging
+ to the SASL application, that handles unpacking, installation,
+ and removal of release packages. It is interfaced through
+ the module <c>release_handler</c>, which is described in detail in
+ <c>release_handler(3)</c>.</p>
+ <p>Assuming there is a target system up and running with
+ installation root directory <c>$ROOT</c>, the release package with
+ the new version of the release should be copied to
+ <c>$ROOT/releases</c>.</p>
+ <p>The first action is to <em>unpack</em> the release package,
+ the files are then extracted from the package:</p>
+ <code type="none">
+release_handler:unpack_release(ReleaseName) => {ok, Vsn}</code>
+ <p><c>ReleaseName</c> is the name of the release package except
+ the <c>.tar.gz</c> extension. <c>Vsn</c> is the version of
+ the unpacked release, as defined in its <c>.rel</c> file.</p>
+ <p>A directory <c>$ROOT/lib/releases/Vsn</c> will be created, where
+ the <c>.rel</c> file, the boot script <c>start.boot</c>,
+ the system configuration file <c>sys.config</c> and <c>relup</c>
+ are placed. For applications with new version numbers,
+ the application directories will be placed under <c>$ROOT/lib</c>.
+ Unchanged applications are not affected.</p>
+ <p>An unpacked release can be <em>installed</em>. The release
+ handler then evaluates the instructions in <c>relup</c>, step by
+ step:</p>
+ <code type="none">
+release_handler:install_release(Vsn) => {ok, FromVsn, []}</code>
+ <p>If an error occurs during the installation, the system is
+ rebooted using the old version of the release. If installation
+ succeeds, the system is afterwards using the new version of
+ the release, but should anything happen and the system is
+ rebooted, it would start using the previous version again. To be
+ made the default version, the newly installed release must be made
+ <em>permanent</em>, which means the previous version becomes
+ <em>old</em>:</p>
+ <code type="none">
+release_handler:make_permanent(Vsn) => ok</code>
+ <p>The system keeps information about which versions are old and
+ permanent in the files <c>$ROOT/releases/RELEASES</c> and
+ <c>$ROOT/releases/start_erl.data</c>.</p>
+ <p>To downgrade from <c>Vsn</c> to <c>FromVsn</c>,
+ <c>install_release</c> must be called again:</p>
+ <code type="none">
+release_handler:install_release(FromVsn) => {ok, Vsn, []}</code>
+ <p>An installed, but not permanent, release can be <em>removed</em>.
+ Information about the release is then deleted from
+ <c>$ROOT/releases/RELEASES</c> and the release specific code,
+ that is the new application directories and
+ the <c>$ROOT/releases/Vsn</c> directory, are removed.</p>
+ <code type="none">
+release_handler:remove_release(Vsn) => ok</code>
+ <p>Example, continued from the previous sections:</p>
+ <p>1) Create a target system as described in <em>System Principles</em> of the first version <c>"A"</c> of <c>ch_rel</c>
+ from
+ the <seealso marker="release_structure#ch_rel">Releases</seealso>
+ chapter. This time <c>sys.config</c> must be included in
+ the release package. If no configuration is needed, the file
+ should contain the empty list:</p>
+ <code type="none">
+[].</code>
+ <p>2) Start the system as a simple target system. Note that in
+ reality, it should be started as an embedded system. However,
+ using <c>erl</c> with the correct boot script and <c>.config</c>
+ file is enough for illustration purposes:</p>
+ <pre>
+% <input>cd $ROOT</input>
+% <input>bin/erl -boot $ROOT/releases/A/start -config $ROOT/releases/A/sys</input>
+...</pre>
+ <p><c>$ROOT</c> is the installation directory of the target system.</p>
+ <p>3) In another Erlang shell, generate start scripts and create a
+ release package for the new version <c>"B"</c>. Remember to
+ include (a possible updated) <c>sys.config</c> and
+ the <c>relup</c> file, see <seealso marker="#relup">Release Upgrade File</seealso> above.</p>
+ <pre>
+1> <input>systools:make_script("ch_rel-2").</input>
+ok
+2> <input>systools:make_tar("ch_rel-2").</input>
+ok</pre>
+ <p>The new release package now contains version "2" of <c>ch_app</c>
+ and the <c>relup</c> file as well:</p>
+ <code type="none">
+% tar tf ch_rel-2.tar
+lib/kernel-2.9/ebin/kernel.app
+lib/kernel-2.9/ebin/application.beam
+...
+lib/stdlib-1.12/ebin/stdlib.app
+lib/stdlib-1.12/ebin/beam_lib.beam
+...
+lib/sasl-1.10/ebin/sasl.app
+lib/sasl-1.10/ebin/sasl.beam
+...
+lib/ch_app-2/ebin/ch_app.app
+lib/ch_app-2/ebin/ch_app.beam
+lib/ch_app-2/ebin/ch_sup.beam
+lib/ch_app-2/ebin/ch3.beam
+releases/B/start.boot
+releases/B/relup
+releases/B/sys.config
+releases/ch_rel-2.rel</code>
+ <p>4) Copy the release package <c>ch_rel-2.tar.gz</c> to
+ the <c>$ROOT/releases</c> directory.</p>
+ <p>5) In the running target system, unpack the release package:</p>
+ <pre>
+1> <input>release_handler:unpack_release("ch_rel-2").</input>
+{ok,"B"}</pre>
+ <p>The new application version <c>ch_app-2</c> is installed under
+ <c>$ROOT/lib</c> next to <c>ch_app-1</c>. The <c>kernel</c>,
+ <c>stdlib</c> and <c>sasl</c> directories are not affected, as
+ they have not changed.</p>
+ <p>Under <c>$ROOT/releases</c>, a new directory <c>B</c> is created,
+ containing <c>ch_rel-2.rel</c>, <c>start.boot</c>,
+ <c>sys.config</c> and <c>relup</c>.</p>
+ <p>6) Check if the function <c>ch3:available/0</c> is available:</p>
+ <pre>
+2> <input>ch3:available().</input>
+** exception error: undefined function ch3:available/0</pre>
+ <p>7) Install the new release. The instructions in
+ <c>$ROOT/releases/B/relup</c> are executed one by one, resulting
+ in the new version of <c>ch3</c> being loaded. The function
+ <c>ch3:available/0</c> is now available:</p>
+ <pre>
+3> <input>release_handler:install_release("B").</input>
+{ok,"A",[]}
+4> <input>ch3:available().</input>
+3
+5> <input>code:which(ch3).</input>
+".../lib/ch_app-2/ebin/ch3.beam"
+6> <input>code:which(ch_sup).</input>
+".../lib/ch_app-1/ebin/ch_sup.beam"</pre>
+ <p>Note that processes in <c>ch_app</c> for which code have not
+ been updated, for example the supervisor, are still evaluating
+ code from <c>ch_app-1</c>.</p>
+ <p>8) If the target system is now rebooted, it will use version "A"
+ again. The "B" version must be made permanent, in order to be
+ used when the system is rebooted.</p>
+ <pre>
+7> <input>release_handler:make_permanent("B").</input>
+ok</pre>
+ </section>
+
+ <section>
+ <marker id="sys"></marker>
+ <title>Updating Application Specifications</title>
+ <p>When a new version of a release is installed, the application
+ specifications are automatically updated for all loaded
+ applications.</p>
+ <note>
+ <p>The information about the new application specifications are
+ fetched from the boot script included in the release package.
+ It is therefore important that the boot script is generated from
+ the same <c>.rel</c> file as is used to build the release
+ package itself.</p>
+ </note>
+ <p>Specifically, the application configuration parameters are
+ automatically updated according to (in increasing priority
+ order):</p>
+ <list type="ordered">
+ <item>The data in the boot script, fetched from the new
+ application resource file <c>App.app</c></item>
+ <item>The new <c>sys.config</c></item>
+ <item>Command line arguments <c>-App Par Val</c></item>
+ </list>
+ <p>This means that parameter values set in the other system
+ configuration files, as well as values set using
+ <c>application:set_env/3</c>, are disregarded.</p>
+ <p>When an installed release is made permanent, the system process
+ <c>init</c> is set to point out the new <c>sys.config</c>.</p>
+ <p>After the installation, the application controller will compare
+ the old and new configuration parameters for all running
+ applications and call the callback function:</p>
+ <code type="none">
+Module:config_change(Changed, New, Removed)</code>
+ <p><c>Module</c> is the application callback module as defined by
+ the <c>mod</c> key in the <c>.app</c> file. <c>Changed</c> and
+ <c>New</c> are lists of <c>{Par,Val}</c> for all changed and
+ added configuration parameters, respectively. <c>Removed</c> is
+ a list of all parameters <c>Par</c> that have been removed.</p>
+ <p>The function is optional and may be omitted when implementing an
+ application callback module.</p>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/release_structure.xml b/system/doc/design_principles/release_structure.xml
new file mode 100644
index 0000000000..2e1daa611a
--- /dev/null
+++ b/system/doc/design_principles/release_structure.xml
@@ -0,0 +1,302 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Releases</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>release_structure.xml</file>
+ </header>
+ <p>This chapter should be read in conjuction with <c>rel(4)</c>,
+ <c>systools(3)</c> and <c>script(4)</c>.</p>
+
+ <section>
+ <title>Release Concept</title>
+ <p>When we have written one or more applications, we might want to
+ create a complete system consisting of these applications and a
+ subset of the Erlang/OTP applications. This is called a
+ <em>release</em>.</p>
+ <p>To do this, we create a <seealso marker="#res_file">release resource file</seealso> which defines which applications
+ are included in the release.</p>
+ <p>The release resource file is used to generate
+ <seealso marker="#boot">boot scripts</seealso> and
+ <seealso marker="#pack">release packages</seealso>. A system
+ which is transfered to and installed at another site is called a
+ <em>target system</em>. How to use a release package to create a
+ target system is described in System Principles.</p>
+ </section>
+
+ <section>
+ <marker id="res_file"></marker>
+ <title>Release Resource File</title>
+ <p>To define a release, we create a <em>release resource file</em>,
+ or in short <c>.rel</c> file, where we specify the name and
+ version of the release, which ERTS version it is based on, and
+ which applications it consists of:</p>
+ <code type="none">
+{release, {Name,Vsn}, {erts, EVsn},
+ [{Application1, AppVsn1},
+ ...
+ {ApplicationN, AppVsnN}]}.</code>
+ <p>The file must be named <c>Rel.rel</c>, where <c>Rel</c> is a
+ unique name.</p>
+ <p><c>Name</c>, <c>Vsn</c> and <c>Evsn</c> are strings.</p>
+ <p>Each <c>Application</c> (atom) and <c>AppVsn</c> (string) is
+ the name and version of an application included in the release.
+ Note the the minimal release based on Erlang/OTP consists of
+ the <c>kernel</c> and <c>stdlib</c> applications, so these
+ applications must be included in the list.</p>
+ <marker id="ch_rel"></marker>
+ <p>Example: We want to make a release of <c>ch_app</c> from
+ the <seealso marker="applications#ch_app">Applications</seealso>
+ chapter. It has the following <c>.app</c> file:</p>
+ <code type="none">
+{application, ch_app,
+ [{description, "Channel allocator"},
+ {vsn, "1"},
+ {modules, [ch_app, ch_sup, ch3]},
+ {registered, [ch3]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {ch_app,[]}}
+ ]}.</code>
+ <p>The <c>.rel</c> file must also contain <c>kernel</c>,
+ <c>stdlib</c> and <c>sasl</c>, since these applications are
+ required by <c>ch_app</c>. We call the file <c>ch_rel-1.rel</c>:</p>
+ <code type="none">
+{release,
+ {"ch_rel", "A"},
+ {erts, "5.3"},
+ [{kernel, "2.9"},
+ {stdlib, "1.12"},
+ {sasl, "1.10"},
+ {ch_app, "1"}]
+}.</code>
+ </section>
+
+ <section>
+ <marker id="boot"></marker>
+ <title>Generating Boot Scripts</title>
+ <p>There are tools in the SASL module <c>systools</c> available to
+ build and check releases. The functions read the <c>.rel</c> and
+ <c>.app</c> files and performs syntax and dependency checks.
+ The function <c>systools:make_script/1,2</c> is used to generate
+ a boot script (see System Principles).</p>
+ <pre>
+1> <input>systools:make_script("ch_rel-1", [local]).</input>
+ok</pre>
+ <p>This creates a boot script, both the readable version
+ <c>ch_rel-1.script</c> and the binary version used by the runtime
+ system, <c>ch_rel-1.boot</c>. <c>"ch_rel-1"</c> is the name of
+ the <c>.rel</c> file, minus the extension. <c>local</c> is an
+ option that means that the directories where the applications are
+ found are used in the boot script, instead of <c>$ROOT/lib</c>.
+ (<c>$ROOT</c> is the root directory of the installed release.)
+ This is a useful way to test a generated boot script locally.</p>
+ <p>When starting Erlang/OTP using the boot script, all applications
+ from the <c>.rel</c> file are automatically loaded and started:</p>
+ <pre>
+% <input>erl -boot ch_rel-1</input>
+Erlang (BEAM) emulator version 5.3
+
+Eshell V5.3 (abort with ^G)
+1>
+=PROGRESS REPORT==== 13-Jun-2003::12:01:15 ===
+ supervisor: {local,sasl_safe_sup}
+ started: [{pid,&lt;0.33.0>},
+ {name,alarm_handler},
+ {mfa,{alarm_handler,start_link,[]}},
+ {restart_type,permanent},
+ {shutdown,2000},
+ {child_type,worker}]
+
+...
+
+=PROGRESS REPORT==== 13-Jun-2003::12:01:15 ===
+ application: sasl
+ started_at: nonode@nohost
+
+...
+=PROGRESS REPORT==== 13-Jun-2003::12:01:15 ===
+ application: ch_app
+ started_at: nonode@nohost</pre>
+ </section>
+
+ <section>
+ <marker id="pack"></marker>
+ <title>Creating a Release Package</title>
+ <p>There is a function <c>systools:make_tar/1,2</c> which takes
+ a <c>.rel</c> file as input and creates a zipped tar-file with
+ the code for the specified applications, a <em>release package</em>.</p>
+ <pre>
+1> <input>systools:make_script("ch_rel-1").</input>
+ok
+2> <input>systools:make_tar("ch_rel-1").</input>
+ok</pre>
+ <p>The release package by default contains the <c>.app</c> files and
+ object code for all applications, structured according to
+ the <seealso marker="applications#app_dir">application directory structure</seealso>, the binary boot script renamed to
+ <c>start.boot</c>, and the <c>.rel</c> file.</p>
+ <pre>
+% <input>tar tf ch_rel-1.tar</input>
+lib/kernel-2.9/ebin/kernel.app
+lib/kernel-2.9/ebin/application.beam
+...
+lib/stdlib-1.12/ebin/stdlib.app
+lib/stdlib-1.12/ebin/beam_lib.beam
+...
+lib/sasl-1.10/ebin/sasl.app
+lib/sasl-1.10/ebin/sasl.beam
+...
+lib/ch_app-1/ebin/ch_app.app
+lib/ch_app-1/ebin/ch_app.beam
+lib/ch_app-1/ebin/ch_sup.beam
+lib/ch_app-1/ebin/ch3.beam
+releases/A/start.boot
+releases/ch_rel-1.rel</pre>
+ <p>Note that a new boot script was generated, without
+ the <c>local</c> option set, before the release package was made.
+ In the release package, all application directories are placed
+ under <c>lib</c>. Also, we do not know where the release package
+ will be installed, so we do not want any hardcoded absolute paths
+ in the boot script here.</p>
+ <p>If a <c>relup</c> file and/or a system configuration file called
+ <c>sys.config</c> is found, these files are included in
+ the release package as well. See
+ <seealso marker="release_handling#req">Release Handling</seealso>.</p>
+ <p>Options can be set to make the release package include source
+ code and the ERTS binary as well.</p>
+ <p>Refer to System Principles for how to install the first target
+ system, using a release package, and to
+ <seealso marker="release_handling">Release Handling</seealso> for
+ how to install a new release package in an existing system.</p>
+ </section>
+
+ <section>
+ <marker id="reldir"></marker>
+ <title>Directory Structure</title>
+ <p>Directory structure for the code installed by the release handler
+ from a release package:</p>
+ <code type="none">
+$ROOT/lib/App1-AVsn1/ebin
+ /priv
+ /App2-AVsn2/ebin
+ /priv
+ ...
+ /AppN-AVsnN/ebin
+ /priv
+ /erts-EVsn/bin
+ /releases/Vsn
+ /bin</code>
+ <taglist>
+ <tag><c>lib</c></tag>
+ <item>Application directories.</item>
+ <tag><c>erts-EVsn/bin</c></tag>
+ <item>Erlang runtime system executables.</item>
+ <tag><c>releases/Vsn</c></tag>
+ <item><c>.rel</c> file and boot script <c>start.boot</c>. <br></br>
+
+ If present in the release package, <br></br>
+<c>relup</c> and/or <c>sys.config</c>.</item>
+ <tag><c>bin</c></tag>
+ <item>Top level Erlang runtime system executables.</item>
+ </taglist>
+ <p>Applications are not required to be located under the
+ <c>$ROOT/lib</c> directory. Accordingly, several installation
+ directories may exist which contain different parts of a
+ system. For example, the previous example could be extended as
+ follows:</p>
+ <pre>
+$SECOND_ROOT/.../SApp1-SAVsn1/ebin
+ /priv
+ /SApp2-SAVsn2/ebin
+ /priv
+ ...
+ /SAppN-SAVsnN/ebin
+ /priv
+
+$THIRD_ROOT/TApp1-TAVsn1/ebin
+ /priv
+ /TApp2-TAVsn2/ebin
+ /priv
+ ...
+ /TAppN-TAVsnN/ebin
+ /priv</pre>
+ <p>The <c>$SECOND_ROOT</c> and <c>$THIRD_ROOT</c> are introduced as
+ <c>variables</c> in the call to the <c>systools:make_script/2</c>
+ function.</p>
+
+ <section>
+ <title>Disk-Less and/or Read-Only Clients</title>
+ <p>If a complete system consists of some disk-less and/or
+ read-only client nodes, a <c>clients</c> directory should be
+ added to the <c>$ROOT</c> directory. By a read-only node we
+ mean a node with a read-only file system.</p>
+ <p>The <c>clients</c> directory should have one sub-directory
+ per supported client node. The name of each client directory
+ should be the name of the corresponding client node. As a
+ minimum, each client directory should contain the <c>bin</c> and
+ <c>releases</c> sub-directories. These directories are used to
+ store information about installed releases and to appoint the
+ current release to the client. Accordingly, the <c>$ROOT</c>
+ directory contains the following:</p>
+ <code type="none">
+$ROOT/...
+ /clients/ClientName1/bin
+ /releases/Vsn
+ /ClientName2/bin
+ /releases/Vsn
+ ...
+ /ClientNameN/bin
+ /releases/Vsn</code>
+ <p>This structure should be used if all clients are running
+ the same type of Erlang machine. If there are clients running
+ different types of Erlang machines, or on different operating
+ systems, the <c>clients</c> directory could be divided into one
+ sub-directory per type of Erlang machine. Alternatively, you
+ can set up one <c>$ROOT</c> per type of machine. For each
+ type, some of the directories specified for the <c>$ROOT</c>
+ directory should be included:</p>
+ <code type="none">
+$ROOT/...
+ /clients/Type1/lib
+ /erts-EVsn
+ /bin
+ /ClientName1/bin
+ /releases/Vsn
+ /ClientName2/bin
+ /releases/Vsn
+ ...
+ /ClientNameN/bin
+ /releases/Vsn
+ ...
+ /TypeN/lib
+ /erts-EVsn
+ /bin
+ ...</code>
+ <p>With this structure, the root directory for clients of
+ <c>Type1</c> is <c>$ROOT/clients/Type1</c>.</p>
+ </section>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/spec_proc.xml b/system/doc/design_principles/spec_proc.xml
new file mode 100644
index 0000000000..f0f62891b6
--- /dev/null
+++ b/system/doc/design_principles/spec_proc.xml
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Sys and Proc_Lib</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>spec_proc.xml</file>
+ </header>
+ <p>The module <c>sys</c> contains functions for simple debugging of
+ processes implemented using behaviours.</p>
+ <p>There are also functions that, together with functions in
+ the module <c>proc_lib</c>, can be used to implement a
+ <em>special process</em>, a process which comply to the OTP design
+ principles without making use of a standard behaviour. They can
+ also be used to implement user defined (non-standard) behaviours.</p>
+ <p>Both <c>sys</c> and <c>proc_lib</c> belong to the STDLIB
+ application.</p>
+
+ <section>
+ <title>Simple Debugging</title>
+ <p>The module <c>sys</c> contains some functions for simple debugging
+ of processes implemented using behaviours. We use the
+ <c>code_lock</c> example from
+ the <seealso marker="fsm#ex">gen_event</seealso> chapter to
+ illustrate this:</p>
+ <pre>
+% <input>erl</input>
+Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
+
+Eshell V5.2.3.6 (abort with ^G)
+1> <input>code_lock:start_link([1,2,3,4]).</input>
+{ok,&lt;0.32.0>}
+2> <input>sys:statistics(code_lock, true).</input>
+ok
+3> <input>sys:trace(code_lock, true).</input>
+ok
+4> <input>code_lock:button(4).</input>
+*DBG* code_lock got event {button,4} in state closed
+ok
+*DBG* code_lock switched to state closed
+5> <input>code_lock:button(3).</input>
+*DBG* code_lock got event {button,3} in state closed
+ok
+*DBG* code_lock switched to state closed
+6> <input>code_lock:button(2).</input>
+*DBG* code_lock got event {button,2} in state closed
+ok
+*DBG* code_lock switched to state closed
+7> <input>code_lock:button(1).</input>
+*DBG* code_lock got event {button,1} in state closed
+ok
+OPEN DOOR
+*DBG* code_lock switched to state open
+*DBG* code_lock got event timeout in state open
+CLOSE DOOR
+*DBG* code_lock switched to state closed
+8> <input>sys:statistics(code_lock, get).</input>
+{ok,[{start_time,{{2003,6,12},{14,11,40}}},
+ {current_time,{{2003,6,12},{14,12,14}}},
+ {reductions,333},
+ {messages_in,5},
+ {messages_out,0}]}
+9> <input>sys:statistics(code_lock, false).</input>
+ok
+10> <input>sys:trace(code_lock, false).</input>
+ok
+11> <input>sys:get_status(code_lock).</input>
+{status,&lt;0.32.0>,
+ {module,gen_fsm},
+ [[{'$ancestors',[&lt;0.30.0>]},
+ {'$initial_call',{gen,init_it,
+ [gen_fsm,&lt;0.30.0>,&lt;0.30.0>,
+ {local,code_lock},
+ code_lock,
+ [1,2,3,4],
+ []]}}],
+ running,&lt;0.30.0>,[],
+ [code_lock,closed,{[],[1,2,3,4]},code_lock,infinity]]}</pre>
+ </section>
+
+ <section>
+ <title>Special Processes</title>
+ <p>This section describes how to write a process which comply to
+ the OTP design principles, without making use of a standard
+ behaviour. Such a process should:</p>
+ <list type="bulleted">
+ <item>be started in a way that makes the process fit into a
+ supervision tree,</item>
+ <item>support the <c>sys</c><seealso marker="#debug">debug facilities</seealso>, and</item>
+ <item>take care of <seealso marker="#msg">system messages</seealso>.</item>
+ </list>
+ <p>System messages are messages with special meaning, used in
+ the supervision tree. Typical system messages are requests for
+ trace output, and requests to suspend or resume process execution
+ (used during release handling). Processes implemented using
+ standard behaviours automatically understand these messages.</p>
+
+ <section>
+ <title>Example</title>
+ <p>The simple server from
+ the <seealso marker="des_princ#ch1">Overview</seealso> chapter,
+ implemented using <c>sys</c> and <c>proc_lib</c> so it fits into
+ a supervision tree:</p>
+ <marker id="ex"></marker>
+ <pre>
+-module(ch4).
+-export([start_link/0]).
+-export([alloc/0, free/1]).
+-export([init/1]).
+-export([system_continue/3, system_terminate/4,
+ write_debug/3]).
+
+start_link() ->
+ proc_lib:start_link(ch4, init, [self()]).
+
+alloc() ->
+ ch4 ! {self(), alloc},
+ receive
+ {ch4, Res} ->
+ Res
+ end.
+
+free(Ch) ->
+ ch4 ! {free, Ch},
+ ok.
+
+init(Parent) ->
+ register(ch4, self()),
+ Chs = channels(),
+ Deb = sys:debug_options([]),
+ proc_lib:init_ack(Parent, {ok, self()}),
+ loop(Chs, Parent, Deb).
+
+loop(Chs, Parent, Deb) ->
+ receive
+ {From, alloc} ->
+ Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
+ ch4, {in, alloc, From}),
+ {Ch, Chs2} = alloc(Chs),
+ From ! {ch4, Ch},
+ Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
+ ch4, {out, {ch4, Ch}, From}),
+ loop(Chs2, Parent, Deb3);
+ {free, Ch} ->
+ Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
+ ch4, {in, {free, Ch}}),
+ Chs2 = free(Ch, Chs),
+ loop(Chs2, Parent, Deb2);
+
+ {system, From, Request} ->
+ sys:handle_system_msg(Request, From, Parent,
+ ch4, Deb, Chs)
+ end.
+
+system_continue(Parent, Deb, Chs) ->
+ loop(Chs, Parent, Deb).
+
+system_terminate(Reason, Parent, Deb, Chs) ->
+ exit(Reason).
+
+write_debug(Dev, Event, Name) ->
+ io:format(Dev, "~p event = ~p~n", [Name, Event]).</pre>
+ <p>Example on how the simple debugging functions in <c>sys</c> can
+ be used for <c>ch4</c> as well:</p>
+ <pre>
+% <input>erl</input>
+Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
+
+Eshell V5.2.3.6 (abort with ^G)
+1> <input>ch4:start_link().</input>
+{ok,&lt;0.30.0>}
+2> <input>sys:statistics(ch4, true).</input>
+ok
+3> <input>sys:trace(ch4, true).</input>
+ok
+4> <input>ch4:alloc().</input>
+ch4 event = {in,alloc,&lt;0.25.0>}
+ch4 event = {out,{ch4,ch1},&lt;0.25.0>}
+ch1
+5> <input>ch4:free(ch1).</input>
+ch4 event = {in,{free,ch1}}
+ok
+6> <input>sys:statistics(ch4, get).</input>
+{ok,[{start_time,{{2003,6,13},{9,47,5}}},
+ {current_time,{{2003,6,13},{9,47,56}}},
+ {reductions,109},
+ {messages_in,2},
+ {messages_out,1}]}
+7> <input>sys:statistics(ch4, false).</input>
+ok
+8> <input>sys:trace(ch4, false).</input>
+ok
+9> <input>sys:get_status(ch4).</input>
+{status,&lt;0.30.0>,
+ {module,ch4},
+ [[{'$ancestors',[&lt;0.25.0>]},{'$initial_call',{ch4,init,[&lt;0.25.0>]}}],
+ running,&lt;0.25.0>,[],
+ [ch1,ch2,ch3]]}</pre>
+ </section>
+
+ <section>
+ <title>Starting the Process</title>
+ <p>A function in the <c>proc_lib</c> module should be used to
+ start the process. There are several possible functions, for
+ example <c>spawn_link/3,4</c> for asynchronous start and
+ <c>start_link/3,4,5</c> for synchronous start.</p>
+ <p>A process started using one of these functions will store
+ information that is needed for a process in a supervision tree,
+ for example about the ancestors and initial call.</p>
+ <p>Also, if the process terminates with another reason than
+ <c>normal</c> or <c>shutdown</c>, a crash report (see SASL
+ User's Guide) is generated.</p>
+ <p>In the example, synchronous start is used. The process is
+ started by calling <c>ch4:start_link()</c>:</p>
+ <code type="none">
+start_link() ->
+ proc_lib:start_link(ch4, init, [self()]).</code>
+ <p><c>ch4:start_link</c> calls the function
+ <c>proc_lib:start_link</c>. This function takes a module name,
+ a function name and an argument list as arguments and spawns
+ and links to a new process. The new process starts by executing
+ the given function, in this case <c>ch4:init(Pid)</c>, where
+ <c>Pid</c> is the pid (<c>self()</c>) of the first process, that
+ is the parent process.</p>
+ <p>In <c>init</c>, all initialization including name registration
+ is done. The new process must also acknowledge that it has been
+ started to the parent:</p>
+ <code type="none">
+init(Parent) ->
+ ...
+ proc_lib:init_ack(Parent, {ok, self()}),
+ loop(...).</code>
+ <p><c>proc_lib:start_link</c> is synchronous and does not return
+ until <c>proc_lib:init_ack</c> has been called.</p>
+ </section>
+
+ <section>
+ <marker id="debug"></marker>
+ <title>Debugging</title>
+ <p>To support the debug facilites in <c>sys</c>, we need a
+ <em>debug structure</em>, a term <c>Deb</c> which is
+ initialized using <c>sys:debug_options/1</c>:</p>
+ <code type="none">
+init(Parent) ->
+ ...
+ Deb = sys:debug_options([]),
+ ...
+ loop(Chs, Parent, Deb).</code>
+ <p><c>sys:debug_options/1</c> takes a list of options as argument.
+ Here the list is empty, which means no debugging is enabled
+ initially. See <c>sys(3)</c> for information about possible
+ options.</p>
+ <p>Then for each <em>system event</em> that we want to be logged
+ or traced, the following function should be called.</p>
+ <code type="none">
+sys:handle_debug(Deb, Func, Info, Event) => Deb1</code>
+ <list type="bulleted">
+ <item>
+ <p><c>Deb</c> is the debug structure.</p>
+ </item>
+ <item>
+ <p><c>Func</c> is a tuple <c>{Module, Name}</c> (or a fun) and
+ should specify a (user defined) function used to format
+ trace output. For each system event, the format function is
+ called as <c>Module:Name(Dev, Event, Info)</c>, where:</p>
+ <list type="bulleted">
+ <item>
+ <p><c>Dev</c> is the IO device to which the output should
+ be printed. See <c>io(3)</c>.</p>
+ </item>
+ <item>
+ <p><c>Event</c> and <c>Info</c> are passed as-is from
+ <c>handle_debug</c>.</p>
+ </item>
+ </list>
+ </item>
+ <item>
+ <p><c>Info</c> is used to pass additional information to
+ <c>Func</c>, it can be any term and is passed as-is.</p>
+ </item>
+ <item>
+ <p><c>Event</c> is the system event. It is up to the user to
+ define what a system event is and how it should be
+ represented, but typically at least incoming and outgoing
+ messages are considered system events and represented by
+ the tuples <c>{in,Msg[,From]}</c> and <c>{out,Msg,To}</c>,
+ respectively.</p>
+ </item>
+ </list>
+ <p><c>handle_debug</c> returns an updated debug structure
+ <c>Deb1</c>.</p>
+ <p>In the example, <c>handle_debug</c> is called for each incoming
+ and outgoing message. The format function <c>Func</c> is
+ the function <c>ch4:write_debug/3</c> which prints the message
+ using <c>io:format/3</c>.</p>
+ <code type="none">
+loop(Chs, Parent, Deb) ->
+ receive
+ {From, alloc} ->
+ Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
+ ch4, {in, alloc, From}),
+ {Ch, Chs2} = alloc(Chs),
+ From ! {ch4, Ch},
+ Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
+ ch4, {out, {ch4, Ch}, From}),
+ loop(Chs2, Parent, Deb3);
+ {free, Ch} ->
+ Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
+ ch4, {in, {free, Ch}}),
+ Chs2 = free(Ch, Chs),
+ loop(Chs2, Parent, Deb2);
+ ...
+ end.
+
+write_debug(Dev, Event, Name) ->
+ io:format(Dev, "~p event = ~p~n", [Name, Event]).</code>
+ </section>
+
+ <section>
+ <marker id="msg"></marker>
+ <title>Handling System Messages</title>
+ <p><em>System messages</em> are received as:</p>
+ <code type="none">
+{system, From, Request}</code>
+ <p>The content and meaning of these messages do not need to be
+ interpreted by the process. Instead the following function
+ should be called:</p>
+ <code type="none">
+sys:handle_system_msg(Request, From, Parent, Module, Deb, State)</code>
+ <p>This function does not return. It will handle the system
+ message and then call:</p>
+ <code type="none">
+Module:system_continue(Parent, Deb, State)</code>
+ <p>if process execution should continue, or:</p>
+ <code type="none">
+Module:system_terminate(Reason, Parent, Deb, State)</code>
+ <p>if the process should terminate. Note that a process in a
+ supervision tree is expected to terminate with the same reason as
+ its parent.</p>
+ <list type="bulleted">
+ <item><c>Request</c> and <c>From</c> should be passed as-is from
+ the system message to the call to <c>handle_system_msg</c>.</item>
+ <item><c>Parent</c> is the pid of the parent.</item>
+ <item><c>Module</c> is the name of the module.</item>
+ <item><c>Deb</c> is the debug structure.</item>
+ <item><c>State</c> is a term describing the internal state and
+ is passed to <c>system_continue</c>/<c>system_terminate</c>.</item>
+ </list>
+ <p>In the example:</p>
+ <code type="none">
+loop(Chs, Parent, Deb) ->
+ receive
+ ...
+
+ {system, From, Request} ->
+ sys:handle_system_msg(Request, From, Parent,
+ ch4, Deb, Chs)
+ end.
+
+system_continue(Parent, Deb, Chs) ->
+ loop(Chs, Parent, Deb).
+
+system_terminate(Reason, Parent, Deb, Chs) ->
+ exit(Reason).</code>
+ <p>If the special process is set to trap exits, note that if
+ the parent process terminates, the expected behavior is to
+ terminate with the same reason:</p>
+ <code type="none">
+init(...) ->
+ ...,
+ process_flag(trap_exit, true),
+ ...,
+ loop(...).
+
+loop(...) ->
+ receive
+ ...
+
+ {'EXIT', Parent, Reason} ->
+ ..maybe some cleaning up here..
+ exit(Reason);
+ ...
+ end.</code>
+ </section>
+ </section>
+
+ <section>
+ <title>User-Defined Behaviours</title>
+ <p>To implement a user-defined behaviour, write code similar to
+ code for a special process but calling functions in a callback
+ module for handling specific tasks.</p>
+ <p>If it is desired that the compiler should warn for missing
+ callback functions, as it does for the OTP behaviours, implement
+ and export the function:</p>
+ <code type="none">
+behaviour_info(callbacks) ->
+ [{Name1,Arity1},...,{NameN,ArityN}].</code>
+ <p>where each <c>{Name,Arity}</c> specifies the name and arity of
+ a callback function.</p>
+ <p>When the compiler encounters the module attribute
+ <c>-behaviour(Behaviour).</c> in a module <c>Mod</c>, it will call
+ <c>Behaviour:behaviour_info(callbacks)</c> and compare the result
+ with the set of functions actually exported from <c>Mod</c>, and
+ issue a warning if any callback function is missing.</p>
+ <p>Example:</p>
+ <code type="none">
+%% User-defined behaviour module
+-module(simple_server).
+-export([start_link/2,...]).
+-export([behaviour_info/1]).
+
+behaviour_info(callbacks) ->
+ [{init,1},
+ {handle_req,1},
+ {terminate,0}].
+
+start_link(Name, Module) ->
+ proc_lib:start_link(?MODULE, init, [self(), Name, Module]).
+
+init(Parent, Name, Module) ->
+ register(Name, self()),
+ ...,
+ Dbg = sys:debug_options([]),
+ proc_lib:init_ack(Parent, {ok, self()}),
+ loop(Parent, Module, Deb, ...).
+
+...</code>
+ <p>In a callback module:</p>
+ <code type="none">
+-module(db).
+-behaviour(simple_server).
+
+-export([init/0, handle_req/1, terminate/0]).
+
+...</code>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/sup4.fig b/system/doc/design_principles/sup4.fig
new file mode 100644
index 0000000000..9127f9797c
--- /dev/null
+++ b/system/doc/design_principles/sup4.fig
@@ -0,0 +1,32 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 2100 750 2550 1200
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 2100 750 2550 750 2550 1200 2100 1200 2100 750
+4 0 -1 0 0 2 14 0.0000 4 150 105 2250 1050 1\001
+-6
+1 4 0 1 -1 7 0 0 -1 0.000 1 0.0000 4762 2700 293 293 4575 2475 4950 2925
+1 4 0 1 -1 7 0 0 -1 0.000 1 0.0000 3112 2775 293 293 2925 2550 3300 3000
+1 4 0 1 -1 7 0 0 -1 0.000 1 0.0000 1987 2775 293 293 1800 2550 2175 3000
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 675 2550 1125 2550 1125 3000 675 3000 675 2550
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 2550 2250 1200
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1950 2475 2325 1200
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2400 1200 3000 2475
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 1200 4500 2550
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 2325 3450 3150
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2625 3225 3525 2325
+4 0 -1 0 0 2 14 0.0000 4 150 240 1875 2850 P1\001
+4 0 -1 0 0 2 14 0.0000 4 150 240 3000 2850 P2\001
+4 0 -1 0 0 2 14 0.0000 4 150 255 4650 2775 Pn\001
+4 0 -1 0 0 0 14 0.0000 4 195 2025 3450 975 One for one supervision\001
+4 0 -1 0 0 0 14 0.0000 4 195 2490 3450 1200 If any child dies it is restarted\001
diff --git a/system/doc/design_principles/sup4.gif b/system/doc/design_principles/sup4.gif
new file mode 100644
index 0000000000..fc099f9b06
--- /dev/null
+++ b/system/doc/design_principles/sup4.gif
Binary files differ
diff --git a/system/doc/design_principles/sup4.ps b/system/doc/design_principles/sup4.ps
new file mode 100644
index 0000000000..2507fcc36e
--- /dev/null
+++ b/system/doc/design_principles/sup4.ps
@@ -0,0 +1,153 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: sup4.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 12:49:21 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 322 151
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-39.0 195.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Polyline
+n 2100 750 m 2550 750 l 2550 1200 l 2100 1200 l cp gs col-1 s gr
+/Times-Bold ff 210.00 scf sf
+2250 1050 m
+gs 1 -1 sc (1) col-1 sh gr
+% Ellipse
+n 4762 2700 293 293 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 3112 2775 293 293 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 1987 2775 293 293 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 675 2550 m 1125 2550 l 1125 3000 l 675 3000 l cp gs col-1 s gr
+% Polyline
+n 900 2550 m 2250 1200 l gs col-1 s gr
+% Polyline
+n 1950 2475 m 2325 1200 l gs col-1 s gr
+% Polyline
+n 2400 1200 m 3000 2475 l gs col-1 s gr
+% Polyline
+n 2475 1200 m 4500 2550 l gs col-1 s gr
+% Polyline
+n 2625 2325 m 3450 3150 l gs col-1 s gr
+% Polyline
+n 2625 3225 m 3525 2325 l gs col-1 s gr
+/Times-Bold ff 210.00 scf sf
+1875 2850 m
+gs 1 -1 sc (P1) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+3000 2850 m
+gs 1 -1 sc (P2) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+4650 2775 m
+gs 1 -1 sc (Pn) col-1 sh gr
+/Times-Roman ff 210.00 scf sf
+3450 975 m
+gs 1 -1 sc (One for one supervision) col-1 sh gr
+/Times-Roman ff 210.00 scf sf
+3450 1200 m
+gs 1 -1 sc (If any child dies it is restarted) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/sup5.fig b/system/doc/design_principles/sup5.fig
new file mode 100644
index 0000000000..554ab28ba0
--- /dev/null
+++ b/system/doc/design_principles/sup5.fig
@@ -0,0 +1,43 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+1 4 0 1 -1 7 0 0 -1 0.000 1 0.0000 4762 2700 293 293 4575 2475 4950 2925
+1 4 0 1 -1 7 0 0 -1 0.000 1 0.0000 3112 2775 293 293 2925 2550 3300 3000
+1 4 0 1 -1 7 0 0 -1 0.000 1 0.0000 1987 2775 293 293 1800 2550 2175 3000
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 675 2550 1125 2550 1125 3000 675 3000 675 2550
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 900 2550 2250 1200
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1950 2475 2325 1200
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2400 1200 3000 2475
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 1200 4500 2550
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 2100 750 2550 750 2550 1200 2100 1200 2100 750
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2775 2325 3450 3225
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2775 3150 3525 2400
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 4350 3075 5100 2250
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 4425 2175 5100 3150
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1650 2325 2325 3150
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1650 3150 2325 2400
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 525 2325 1350 3150
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 525 3150 1350 2325
+4 0 -1 0 0 2 14 0.0000 4 150 240 1875 2850 P1\001
+4 0 -1 0 0 2 14 0.0000 4 150 240 3000 2850 P2\001
+4 0 -1 0 0 2 14 0.0000 4 150 255 4650 2775 Pn\001
+4 0 -1 0 0 0 14 0.0000 4 195 2310 3525 1005 If any child dies all children\001
+4 0 -1 0 0 0 14 0.0000 4 150 3015 3525 1260 are terminated and all are restarted\001
+4 0 -1 0 0 2 14 0.0000 4 105 105 2250 1050 a\001
+4 0 -1 0 0 0 14 0.0000 4 195 2040 3525 750 all-for-one supervision\001
diff --git a/system/doc/design_principles/sup5.gif b/system/doc/design_principles/sup5.gif
new file mode 100644
index 0000000000..1197278f63
--- /dev/null
+++ b/system/doc/design_principles/sup5.gif
Binary files differ
diff --git a/system/doc/design_principles/sup5.ps b/system/doc/design_principles/sup5.ps
new file mode 100644
index 0000000000..40eb07a132
--- /dev/null
+++ b/system/doc/design_principles/sup5.ps
@@ -0,0 +1,168 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: sup5.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 12:49:29 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 368 160
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-30.0 195.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Ellipse
+n 4762 2700 293 293 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 3112 2775 293 293 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 1987 2775 293 293 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 675 2550 m 1125 2550 l 1125 3000 l 675 3000 l cp gs col-1 s gr
+% Polyline
+n 900 2550 m 2250 1200 l gs col-1 s gr
+% Polyline
+n 1950 2475 m 2325 1200 l gs col-1 s gr
+% Polyline
+n 2400 1200 m 3000 2475 l gs col-1 s gr
+% Polyline
+n 2475 1200 m 4500 2550 l gs col-1 s gr
+% Polyline
+n 2100 750 m 2550 750 l 2550 1200 l 2100 1200 l cp gs col-1 s gr
+% Polyline
+n 2775 2325 m 3450 3225 l gs col-1 s gr
+% Polyline
+n 2775 3150 m 3525 2400 l gs col-1 s gr
+% Polyline
+n 4350 3075 m 5100 2250 l gs col-1 s gr
+% Polyline
+n 4425 2175 m 5100 3150 l gs col-1 s gr
+% Polyline
+n 1650 2325 m 2325 3150 l gs col-1 s gr
+% Polyline
+n 1650 3150 m 2325 2400 l gs col-1 s gr
+% Polyline
+n 525 2325 m 1350 3150 l gs col-1 s gr
+% Polyline
+n 525 3150 m 1350 2325 l gs col-1 s gr
+/Times-Bold ff 210.00 scf sf
+1875 2850 m
+gs 1 -1 sc (P1) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+3000 2850 m
+gs 1 -1 sc (P2) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+4650 2775 m
+gs 1 -1 sc (Pn) col-1 sh gr
+/Times-Roman ff 210.00 scf sf
+3525 1005 m
+gs 1 -1 sc (If any child dies all children) col-1 sh gr
+/Times-Roman ff 210.00 scf sf
+3525 1260 m
+gs 1 -1 sc (are terminated and all are restarted) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+2250 1050 m
+gs 1 -1 sc (a) col-1 sh gr
+/Times-Roman ff 210.00 scf sf
+3525 750 m
+gs 1 -1 sc (all-for-one supervision) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/sup6.fig b/system/doc/design_principles/sup6.fig
new file mode 100644
index 0000000000..9947cbb67c
--- /dev/null
+++ b/system/doc/design_principles/sup6.fig
@@ -0,0 +1,46 @@
+#FIG 3.1
+Landscape
+Center
+Inches
+1200 2
+6 2100 750 2550 1200
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 2100 750 2550 750 2550 1200 2100 1200 2100 750
+4 0 -1 0 0 2 14 0.0000 4 150 105 2250 1050 1\001
+-6
+6 1200 1650 1650 2100
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 1200 1650 1650 1650 1650 2100 1200 2100 1200 1650
+4 0 -1 0 0 2 14 0.0000 4 150 105 1350 1950 1\001
+-6
+6 3975 2850 4425 3300
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 3975 2850 4425 2850 4425 3300 3975 3300 3975 2850
+4 0 -1 0 0 2 14 0.0000 4 150 105 4125 3150 1\001
+-6
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 5025 4125 270 270 5025 4125 5175 4350
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 1425 3075 270 270 1425 3075 1575 3300
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 2250 4125 270 270 2250 4125 2400 4350
+1 3 0 1 -1 7 0 0 -1 0.000 1 0.0000 3900 4125 270 270 3900 4125 4050 4350
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2325 1200 1425 1650
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2400 1200 3300 1650
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3300 2100 2550 2850
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 3375 2100 4125 2850
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 2475 3300 2325 3825
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 4200 3300 3900 3825
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 4275 3300 4875 3900
+2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 2
+ 1425 2775 1425 2100
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 3075 1650 3525 1650 3525 2100 3075 2100 3075 1650
+2 2 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 5
+ 2325 2850 2775 2850 2775 3300 2325 3300 2325 2850
+4 0 -1 0 0 2 14 0.0000 4 105 105 3225 1950 a\001
+4 0 -1 0 0 2 14 0.0000 4 105 105 2475 3150 a\001
diff --git a/system/doc/design_principles/sup6.gif b/system/doc/design_principles/sup6.gif
new file mode 100644
index 0000000000..2016f5bf67
--- /dev/null
+++ b/system/doc/design_principles/sup6.gif
Binary files differ
diff --git a/system/doc/design_principles/sup6.ps b/system/doc/design_principles/sup6.ps
new file mode 100644
index 0000000000..3e8a8d2ed4
--- /dev/null
+++ b/system/doc/design_principles/sup6.ps
@@ -0,0 +1,163 @@
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: sup6.fig
+%%Creator: fig2dev Version 3.1 Patchlevel 2
+%%CreationDate: Thu May 15 12:49:34 1997
+%%For: jocke@akvavit (Joakim Greben|,ETX/B/DUP)
+%Magnification: 1.00
+%%Orientation: Portrait
+%%BoundingBox: 0 0 251 221
+%%Pages: 0
+%%BeginSetup
+%%IncludeFeature: *PageSize A4
+%%EndSetup
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+
+end
+save
+-68.0 265.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+10 setmiterlimit
+n 0 842 m 0 0 l 595 0 l 595 842 l cp clip
+ 0.06000 0.06000 sc
+7.500 slw
+% Polyline
+n 2100 750 m 2550 750 l 2550 1200 l 2100 1200 l cp gs col-1 s gr
+/Times-Bold ff 210.00 scf sf
+2250 1050 m
+gs 1 -1 sc (1) col-1 sh gr
+% Polyline
+n 1200 1650 m 1650 1650 l 1650 2100 l 1200 2100 l cp gs col-1 s gr
+/Times-Bold ff 210.00 scf sf
+1350 1950 m
+gs 1 -1 sc (1) col-1 sh gr
+% Polyline
+n 3975 2850 m 4425 2850 l 4425 3300 l 3975 3300 l cp gs col-1 s gr
+/Times-Bold ff 210.00 scf sf
+4125 3150 m
+gs 1 -1 sc (1) col-1 sh gr
+% Ellipse
+n 5025 4125 270 270 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 1425 3075 270 270 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 2250 4125 270 270 0 360 DrawEllipse gs col-1 s gr
+
+% Ellipse
+n 3900 4125 270 270 0 360 DrawEllipse gs col-1 s gr
+
+% Polyline
+n 2325 1200 m 1425 1650 l gs col-1 s gr
+% Polyline
+n 2400 1200 m 3300 1650 l gs col-1 s gr
+% Polyline
+n 3300 2100 m 2550 2850 l gs col-1 s gr
+% Polyline
+n 3375 2100 m 4125 2850 l gs col-1 s gr
+% Polyline
+n 2475 3300 m 2325 3825 l gs col-1 s gr
+% Polyline
+n 4200 3300 m 3900 3825 l gs col-1 s gr
+% Polyline
+n 4275 3300 m 4875 3900 l gs col-1 s gr
+% Polyline
+n 1425 2775 m 1425 2100 l gs col-1 s gr
+% Polyline
+n 3075 1650 m 3525 1650 l 3525 2100 l 3075 2100 l cp gs col-1 s gr
+% Polyline
+n 2325 2850 m 2775 2850 l 2775 3300 l 2325 3300 l cp gs col-1 s gr
+/Times-Bold ff 210.00 scf sf
+3225 1950 m
+gs 1 -1 sc (a) col-1 sh gr
+/Times-Bold ff 210.00 scf sf
+2475 3150 m
+gs 1 -1 sc (a) col-1 sh gr
+$F2psEnd
+rs
diff --git a/system/doc/design_principles/sup_princ.xml b/system/doc/design_principles/sup_princ.xml
new file mode 100644
index 0000000000..067fd31961
--- /dev/null
+++ b/system/doc/design_principles/sup_princ.xml
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>1997</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
+ </copyright>
+ <legalnotice>
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
+ </legalnotice>
+
+ <title>Supervisor Behaviour</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>sup_princ.xml</file>
+ </header>
+ <p>This section should be read in conjunction with
+ <c>supervisor(3)</c>, where all details about the supervisor
+ behaviour is given.</p>
+
+ <section>
+ <title>Supervision Principles</title>
+ <p>A supervisor is responsible for starting, stopping and
+ monitoring its child processes. The basic idea of a supervisor is
+ that it should keep its child processes alive by restarting them
+ when necessary.</p>
+ <p>Which child processes to start and monitor is specified by a
+ list of <seealso marker="#spec">child specifications</seealso>.
+ The child processes are started in the order specified by this
+ list, and terminated in the reversed order.</p>
+ </section>
+
+ <section>
+ <title>Example</title>
+ <p>The callback module for a supervisor starting the server from
+ the <seealso marker="gen_server_concepts#ex">gen_server chapter</seealso>
+ could look like this:</p>
+ <marker id="ex"></marker>
+ <code type="none">
+-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]}]}}.</code>
+ <p><c>one_for_one</c> is the <seealso marker="#strategy">restart strategy</seealso>.</p>
+ <p>1 and 60 defines the <seealso marker="#frequency">maximum restart frequency</seealso>.</p>
+ <p>The tuple <c>{ch3, ...}</c> is a <seealso marker="#spec">child specification</seealso>.</p>
+ </section>
+
+ <section>
+ <marker id="strategy"></marker>
+ <title>Restart Strategy</title>
+
+ <section>
+ <title>one_for_one</title>
+ <p>If a child process terminates, only that process is restarted.</p>
+ <marker id="sup4"></marker>
+ <image file="../design_principles/sup4.gif">
+ <icaption>One_For_One Supervision</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>one_for_all</title>
+ <p>If a child process terminates, all other child processes are
+ terminated and then all child processes, including
+ the terminated one, are restarted.</p>
+ <marker id="sup5"></marker>
+ <image file="../design_principles/sup5.gif">
+ <icaption>One_For_All Supervision</icaption>
+ </image>
+ </section>
+
+ <section>
+ <title>rest_for_one</title>
+ <p>If a child process terminates, the 'rest' of the child
+ processes -- i.e. the child processes after the terminated
+ process in start order -- are terminated. Then the terminated
+ child process and the rest of the child processes are restarted.</p>
+ </section>
+ </section>
+
+ <section>
+ <marker id="frequency"></marker>
+ <title>Maximum Restart Frequency</title>
+ <p>The supervisors have a built-in mechanism to limit the number of
+ restarts which can occur in a given time interval. This is
+ determined by the values of the two parameters <c>MaxR</c> and
+ <c>MaxT</c> in the start specification returned by the callback
+ function <c>init</c>:</p>
+ <code type="none">
+init(...) ->
+ {ok, {{RestartStrategy, MaxR, MaxT},
+ [ChildSpec, ...]}}.</code>
+ <p>If more than <c>MaxR</c> number of restarts occur in the last
+ <c>MaxT</c> seconds, then the supervisor terminates all the child
+ processes and then itself.</p>
+ <p>When the supervisor terminates, then the next higher level
+ supervisor takes some action. It either restarts the terminated
+ supervisor, or terminates itself.</p>
+ <p>The intention of the restart mechanism is to prevent a situation
+ where a process repeatedly dies for the same reason, only to be
+ restarted again.</p>
+ </section>
+
+ <section>
+ <marker id="spec"></marker>
+ <title>Child Specification</title>
+ <p>This is the type definition for a child specification:</p>
+ <code type="none"><![CDATA[
+{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() &gt;=0 | infinity
+ Type = worker | supervisor
+ Modules = [Module] | dynamic
+ Module = atom()]]></code>
+ <list type="bulleted">
+ <item>
+ <p><c>Id</c> is a name that is used to identify the child
+ specification internally by the supervisor.</p>
+ </item>
+ <item>
+ <p><c>StartFunc</c> defines the function call used to start
+ the child process. It is a module-function-arguments tuple
+ used as <c>apply(M, F, A)</c>.</p>
+ <p>It should be (or result in) a call to
+ <c>supervisor:start_link</c>, <c>gen_server:start_link</c>,
+ <c>gen_fsm:start_link</c> or <c>gen_event:start_link</c>.
+ (Or a function compliant with these functions, see
+ <c>supervisor(3)</c> for details.</p>
+ </item>
+ <item>
+ <p><c>Restart</c> defines when a terminated child process should
+ be restarted.</p>
+ <list type="bulleted">
+ <item>A <c>permanent</c> child process is always restarted.</item>
+ <item>A <c>temporary</c> child process is never restarted.</item>
+ <item>A <c>transient</c> child process is restarted only if it
+ terminates abnormally, i.e. with another exit reason than
+ <c>normal</c>.</item>
+ </list>
+ </item>
+ <item>
+ <marker id="shutdown"></marker>
+ <p><c>Shutdown</c> defines how a child process should be
+ terminated.</p>
+ <list type="bulleted">
+ <item><c>brutal_kill</c> means the child process is
+ unconditionally terminated using <c>exit(Child, kill)</c>.</item>
+ <item>An integer timeout value means that the supervisor tells
+ the child process to terminate by calling
+ <c>exit(Child, shutdown)</c> and then waits for an exit
+ signal back. If no exit signal is received within
+ the specified time, the child process is unconditionally
+ terminated using <c>exit(Child, kill)</c>.</item>
+ <item>If the child process is another supervisor, it should be
+ set to <c>infinity</c> to give the subtree enough time to
+ shutdown.</item>
+ </list>
+ </item>
+ <item>
+ <p><c>Type</c> specifies if the child process is a supervisor or
+ a worker.</p>
+ </item>
+ <item>
+ <p><c>Modules</c> should be a list with one element
+ <c>[Module]</c>, where <c>Module</c> is the name of
+ the callback module, if the child process is a supervisor,
+ gen_server or gen_fsm. If the child process is a gen_event,
+ <c>Modules</c> should be <c>dynamic</c>.</p>
+ <p>This information is used by the release handler during
+ upgrades and downgrades, see
+ <seealso marker="release_handling">Release Handling</seealso>.</p>
+ </item>
+ </list>
+ <p>Example: The child specification to start the server <c>ch3</c>
+ in the example above looks like:</p>
+ <code type="none">
+{ch3,
+ {ch3, start_link, []},
+ permanent, brutal_kill, worker, [ch3]}</code>
+ <p>Example: A child specification to start the event manager from
+ the chapter about
+ <seealso marker="events#mgr">gen_event</seealso>:</p>
+ <code type="none">
+{error_man,
+ {gen_event, start_link, [{local, error_man}]},
+ permanent, 5000, worker, dynamic}</code>
+ <p>Both the server and event manager are registered processes which
+ can be expected to be accessible at all times, thus they are
+ specified to be <c>permanent</c>.</p>
+ <p><c>ch3</c> does not need to do any cleaning up before
+ termination, thus no shutdown time is needed but
+ <c>brutal_kill</c> should be sufficient. <c>error_man</c> may
+ need some time for the event handlers to clean up, thus
+ <c>Shutdown</c> is set to 5000 ms.</p>
+ <p>Example: A child specification to start another supervisor:</p>
+ <code type="none">
+{sup,
+ {sup, start_link, []},
+ transient, infinity, supervisor, [sup]}</code>
+ </section>
+
+ <section>
+ <marker id="super_tree"></marker>
+ <title>Starting a Supervisor</title>
+ <p>In the example above, the supervisor is started by calling
+ <c>ch_sup:start_link()</c>:</p>
+ <code type="none">
+start_link() ->
+ supervisor:start_link(ch_sup, []).</code>
+ <p><c>ch_sup:start_link</c> calls the function
+ <c>supervisor:start_link/2</c>. This function spawns and links to
+ a new process, a supervisor.</p>
+ <list type="bulleted">
+ <item>The first argument, <c>ch_sup</c>, is the name of
+ the callback module, that is the module where the <c>init</c>
+ callback function is located.</item>
+ <item>The second argument, [], is a term which is passed as-is to
+ the callback function <c>init</c>. Here, <c>init</c> does not
+ need any indata and ignores the argument.</item>
+ </list>
+ <p>In this case, the supervisor is not registered. Instead its pid
+ must be used. A name can be specified by calling
+ <c>supervisor:start_link({local, Name}, Module, Args)</c> or
+ <c>supervisor:start_link({global, Name}, Module, Args)</c>.</p>
+ <p>The new supervisor process calls the callback function
+ <c>ch_sup:init([])</c>. <c>init</c> is expected to return
+ <c>{ok, StartSpec}</c>:</p>
+ <code type="none">
+init(_Args) ->
+ {ok, {{one_for_one, 1, 60},
+ [{ch3, {ch3, start_link, []},
+ permanent, brutal_kill, worker, [ch3]}]}}.</code>
+ <p>The supervisor then starts all its child processes according to
+ the child specifications in the start specification. In this case
+ there is one child process, <c>ch3</c>.</p>
+ <p>Note that <c>supervisor:start_link</c> is synchronous. It does
+ not return until all child processes have been started.</p>
+ </section>
+
+ <section>
+ <title>Adding a Child Process</title>
+ <p>In addition to the static supervision tree, we can also add
+ dynamic child processes to an existing supervisor with
+ the following call:</p>
+ <code type="none">
+supervisor:start_child(Sup, ChildSpec)</code>
+ <p><c>Sup</c> is the pid, or name, of the supervisor.
+ <c>ChildSpec</c> is a <seealso marker="#spec">child specification</seealso>.</p>
+ <p>Child processes added using <c>start_child/2</c> behave in
+ the same manner as the other child processes, with the following
+ important exception: If a supervisor dies and is re-created, then
+ all child processes which were dynamically added to the supervisor
+ will be lost.</p>
+ </section>
+
+ <section>
+ <title>Stopping a Child Process</title>
+ <p>Any child process, static or dynamic, can be stopped in
+ accordance with the shutdown specification:</p>
+ <code type="none">
+supervisor:terminate_child(Sup, Id)</code>
+ <p>The child specification for a stopped child process is deleted
+ with the following call:</p>
+ <code type="none">
+supervisor:delete_child(Sup, Id)</code>
+ <p><c>Sup</c> is the pid, or name, of the supervisor.
+ <c>Id</c> is the id specified in the <seealso marker="#spec">child specification</seealso>.</p>
+ <p>As with dynamically added child processes, the effects of
+ deleting a static child process is lost if the supervisor itself
+ restarts.</p>
+ </section>
+
+ <section>
+ <title>Simple-One-For-One Supervisors</title>
+ <p>A supervisor with restart strategy <c>simple_one_for_one</c> is
+ a simplified one_for_one supervisor, where all child processes are
+ dynamically added instances of the same process.</p>
+ <p>Example of a callback module for a simple_one_for_one supervisor:</p>
+ <code type="none">
+-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]}]}}.</code>
+ <p>When started, the supervisor will not start any child processes.
+ Instead, all child processes are added dynamically by calling:</p>
+ <code type="none">
+supervisor:start_child(Sup, List)</code>
+ <p><c>Sup</c> is the pid, or name, of the supervisor.
+ <c>List</c> is an arbitrary list of terms which will be added to
+ the list of arguments specified in the child specification. If
+ the start function is specified as <c>{M, F, A}</c>, then
+ the child process is started by calling
+ <c>apply(M, F, A++List)</c>.</p>
+ <p>For example, adding a child to <c>simple_sup</c> above:</p>
+ <code type="none">
+supervisor:start_child(Pid, [id1])</code>
+ <p>results in the child process being started by calling
+ <c>apply(call, start_link, []++[id1])</c>, or actually:</p>
+ <code type="none">
+call:start_link(id1)</code>
+ </section>
+
+ <section>
+ <title>Stopping</title>
+ <p>Since the supervisor is part of a supervision tree, it will
+ automatically be terminated by its supervisor. When asked to
+ shutdown, it will terminate all child processes in reversed start
+ order according to the respective shutdown specifications, and
+ then terminate itself.</p>
+ </section>
+</chapter>
+
diff --git a/system/doc/design_principles/warning.gif b/system/doc/design_principles/warning.gif
new file mode 100644
index 0000000000..96af52360e
--- /dev/null
+++ b/system/doc/design_principles/warning.gif
Binary files differ
diff --git a/system/doc/design_principles/xmlfiles.mk b/system/doc/design_principles/xmlfiles.mk
new file mode 100644
index 0000000000..f34d1c9a0f
--- /dev/null
+++ b/system/doc/design_principles/xmlfiles.mk
@@ -0,0 +1,32 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+#
+DESIGN_PRINCIPLES_CHAPTER_FILES = \
+ applications.xml \
+ appup_cookbook.xml \
+ des_princ.xml \
+ distributed_applications.xml \
+ events.xml \
+ fsm.xml \
+ gen_server_concepts.xml \
+ included_applications.xml \
+ release_handling.xml \
+ release_structure.xml \
+ spec_proc.xml \
+ sup_princ.xml