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/Makefile4
-rw-r--r--system/doc/design_principles/appup_cookbook.xml61
-rw-r--r--system/doc/design_principles/make.dep31
-rw-r--r--system/doc/design_principles/release_handling.xml76
-rw-r--r--system/doc/design_principles/release_structure.xml20
-rw-r--r--system/doc/design_principles/spec_proc.xml50
-rw-r--r--system/doc/design_principles/sup_princ.xml21
7 files changed, 177 insertions, 86 deletions
diff --git a/system/doc/design_principles/Makefile b/system/doc/design_principles/Makefile
index b3fe136644..bffff75be2 100644
--- a/system/doc/design_principles/Makefile
+++ b/system/doc/design_principles/Makefile
@@ -1,7 +1,7 @@
#
# %CopyrightBegin%
#
-# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+# Copyright Ericsson AB 1997-2011. 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
@@ -79,6 +79,8 @@ DVIPS_FLAGS +=
# ----------------------------------------------------
# Targets
# ----------------------------------------------------
+_create_dirs := $(shell mkdir -p $(HTMLDIR))
+
$(HTMLDIR)/%.gif: %.gif
$(INSTALL_DATA) $< $@
diff --git a/system/doc/design_principles/appup_cookbook.xml b/system/doc/design_principles/appup_cookbook.xml
index bc61578953..798b23d847 100644
--- a/system/doc/design_principles/appup_cookbook.xml
+++ b/system/doc/design_principles/appup_cookbook.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -603,25 +603,60 @@ code_change(_OldVsn, State, port) ->
</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>
+ <title>Emulator Restart and Upgrade</title>
+ <p>There are two upgrade instructions that will restart the emulator:</p>
+ <taglist>
+ <tag><c>restart_new_emulator</c></tag>
+ <item>Intended for when erts, kernel, stdlib or sasl is
+ upgraded. It is automatically added when the relup file is
+ generated by <c>systools:make_relup/3,4</c>. It is executed
+ before all other upgrade instructions. See
+ <seealso marker="release_handling#restart_new_emulator_instr">Release
+ Handling</seealso> for more information about this
+ instruction.</item>
+ <tag><c>restart_emulator</c></tag>
+ <item>Used when a restart of the emulator is required after all
+ other upgrade instructions are executed. See
+ <seealso marker="release_handling#restart_emulator_instr">Release
+ Handling</seealso> for more information about this
+ instruction.</item>
+ </taglist>
+
+ <p>If an emulator restart is necessary and no upgrade instructions
+ are needed, i.e. if the restart itself is enough for the
+ upgraded applications to start running the new versions, a very
+ simple <c>.relup</c> file can be created manually:</p>
<code type="none">
{"B",
[{"A",
[],
- [restart_new_emulator]}],
+ [restart_emulator]}],
[{"A",
[],
- [restart_new_emulator]}]
+ [restart_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>
+ <p>In this case, 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>
+ </section>
+
+ <section>
+ <title>Emulator Upgrade from pre OTP R15</title>
+ <p>From OTP R15, an emulator upgrade is performed by restarting
+ the emulator with new versions of the core applications
+ (<c>kernel</c>, <c>stdlib</c> and <c>sasl</c>) before loading code
+ and running upgrade instruction for other applications. For this
+ to work, the release to upgrade from must includes OTP R15 or
+ later. For the case where the release to upgrade from includes an
+ earlier emulator version, <c>systools:make_relup</c> will create a
+ backwards compatible relup file. This means that all upgrade
+ instructions will be executed before the emulator is
+ restarted. The new application code will therefore be loaded into
+ the old emulator. If the new code is compiled with the new
+ emulator, there might be cases where the beam format has changed
+ and beam files can not be loaded. To overcome this problem, the
+ new code should be compiled with the old emulator.</p>
</section>
</chapter>
diff --git a/system/doc/design_principles/make.dep b/system/doc/design_principles/make.dep
deleted file mode 100644
index 05dd2333fb..0000000000
--- a/system/doc/design_principles/make.dep
+++ /dev/null
@@ -1,31 +0,0 @@
-# ----------------------------------------------------
-# >>>> 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/release_handling.xml b/system/doc/design_principles/release_handling.xml
index 1d62c242c0..4378b6599c 100644
--- a/system/doc/design_principles/release_handling.xml
+++ b/system/doc/design_principles/release_handling.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -178,13 +178,13 @@
<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
+ that are 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
+ described. The complete list of instructions can be found in
<c>appup(4)</c>.</p>
<p>First, some definitions:</p>
<taglist>
@@ -239,9 +239,10 @@
<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>
+ <p>When a module is to be updated, the release handler finds
+ which processes that are <em>using</em> the module 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
@@ -265,8 +266,8 @@
<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>
+ since the code server then 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">
@@ -294,7 +295,7 @@
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>
+ <p>Instruction for restarting an application:</p>
<code type="none">
{restart_application, Application}</code>
<p>Restarting an application means that the application is stopped
@@ -313,18 +314,35 @@
</section>
<section>
+ <marker id="restart_new_emulator_instr"></marker>
<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
+ version, or when any of the core applications kernel, stdlib
+ or sasl is upgraded. If a system reboot is needed for some
+ other reason, the <c>restart_emulator</c> instruction should
+ be used instead.</p>
+ <p>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
+ <p>The <c>restart_new_emulator</c> instruction shall always be
+ the very first instruction in a relup. If the relup is
+ generated by <c>systools:make_relup/3,4</c> this is
+ automatically ensured.</p>
+ <p>When the release handler encounters the instruction, it first
+ generates a temporary boot file, which starts the new versions
+ of the emulator and the core applications. Then 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>
+ the system is rebooted by the heart program, using the
+ temporary boot file. After the reboot, the rest of the relup
+ instructions are executed. This is done as a part of the
+ temporary boot script.</p>
+ <p>An info report is written when the upgrade is completed. To
+ programatically find out if the upgrade is complete,
+ call <c>release_handler:which_releases(current)</c> and check
+ if it returns the expected (i.e. the new) release.</p>
+ <p>The new release version must be made permanent when the new
+ emulator is up and running. Otherwise, the old version will be
+ 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
@@ -333,6 +351,25 @@
by using the SASL configuration parameter <c>start_prg</c>, see
<c>sasl(6)</c>.</p>
</section>
+
+ <section>
+ <marker id="restart_emulator_instr"></marker>
+ <title>restart_emulator (low-level)</title>
+ <p>This instruction is not related to upgrades of erts or any of
+ the core applications. It can be used by any application to
+ force a restart of the emulator after all upgrade instructions
+ are executed.</p>
+ <p>There can only be one <c>restart_emulator</c> instruction in
+ a relup script, and it shall always be placed at the end. If
+ the relup is generated by <c>systools:make_relup/3,4</c> this
+ is automatically ensured.</p>
+ <p>When the release handler encounters the instruction, it shuts
+ down the 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. No more upgrade instruction will be
+ executed after the restart.</p>
+ </section>
</section>
<section>
@@ -545,8 +582,8 @@ release_handler:remove_release(Vsn) => ok</code>
[].</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>
+ using <c>erl</c> with the correct boot script and config 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>
@@ -581,6 +618,7 @@ lib/ch_app-2/ebin/ch3.beam
releases/B/start.boot
releases/B/relup
releases/B/sys.config
+releases/B/ch_rel-2.rel
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>
diff --git a/system/doc/design_principles/release_structure.xml b/system/doc/design_principles/release_structure.xml
index 2e1daa611a..8aea0e1a10 100644
--- a/system/doc/design_principles/release_structure.xml
+++ b/system/doc/design_principles/release_structure.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>2003</year><year>2009</year>
+ <year>2003</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -61,12 +61,14 @@
{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><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
+ Note that 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>
+ <p>If the release is to be upgraded, it must also include
+ the <c>sasl</c> application.</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>
@@ -173,6 +175,7 @@ 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/A/ch_rel-1.rel
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.
@@ -180,6 +183,17 @@ releases/ch_rel-1.rel</pre>
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>The release resource file <c>mysystem.rel</c> is duplicated in
+ the tar file. Originally, this file was only stored in
+ the <c>releases</c> directory in order to make it possible for
+ the <c>release_handler</c> to extract this file
+ separately. After unpacking the tar file, <c>release_handler</c>
+ would automatically copy the file
+ to <c>releases/FIRST</c>. However, sometimes the tar file is
+ unpacked without involving the <c>release_handler</c> (e.g. when
+ unpacking the first target system) and therefore the file is now
+ instead duplicated in the tar file so no manual copying is
+ necessary.</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
diff --git a/system/doc/design_principles/spec_proc.xml b/system/doc/design_principles/spec_proc.xml
index f0f62891b6..1bc2d32461 100644
--- a/system/doc/design_principles/spec_proc.xml
+++ b/system/doc/design_principles/spec_proc.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2009</year>
+ <year>1997</year><year>2011</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -411,30 +411,48 @@ loop(...) ->
<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>
+ <p>If it is desired that the compiler should warn for missing callback
+ functions, as it does for the OTP behaviours, add callback attributes in the
+ behaviour module to describe the expected callbacks:</p>
+ <code type="none">
+-callback Name1(Arg1_1, Arg1_2, ..., Arg1_N1) -> Res1.
+-callback Name2(Arg2_1, Arg2_2, ..., Arg2_N2) -> Res2.
+...
+-callback NameM(ArgM_1, ArgM_2, ..., ArgM_NM) -> ResM.</code>
+ <p>where <c>NameX</c> are the names of the expected callbacks and
+ <c>ArgX_Y</c>, <c>ResX</c> are types as they are described in Specifications
+ for functions in <seealso marker="../reference_manual/typespec">Types and
+ Function Specifications</seealso>. The whole syntax of spec attributes is
+ supported by callback attributes.</p>
+ <p>Alternatively you may directly 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>where each <c>{Name,Arity}</c> specifies the name and arity of a callback
+ function. This function is otherwise automatically generated by the compiler
+ using the callback attributes.</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>
+ <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}].
+-callback init(State :: term()) -> 'ok'.
+-callback handle_req(Req :: term(), State :: term()) -> {'ok', Reply :: term()}.
+-callback terminate() -> 'ok'.
+
+%% Alternatively you may define:
+%%
+%% -export([behaviour_info/1]).
+%% behaviour_info(callbacks) ->
+%% [{init,1},
+%% {handle_req,2},
+%% {terminate,0}].
start_link(Name, Module) ->
proc_lib:start_link(?MODULE, init, [self(), Name, Module]).
@@ -452,7 +470,7 @@ init(Parent, Name, Module) ->
-module(db).
-behaviour(simple_server).
--export([init/0, handle_req/1, terminate/0]).
+-export([init/0, handle_req/2, terminate/0]).
...</code>
</section>
diff --git a/system/doc/design_principles/sup_princ.xml b/system/doc/design_principles/sup_princ.xml
index 2748f21bbe..5b8fd604c8 100644
--- a/system/doc/design_principles/sup_princ.xml
+++ b/system/doc/design_principles/sup_princ.xml
@@ -160,10 +160,13 @@ init(...) ->
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>temporary</c> child process is never restarted
+ (not even when the supervisor's restart strategy
+ is <c>rest_for_one</c> or <c>one_for_all</c> and a sibling's
+ death causes the temporary process to be terminated).</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>
+ <c>normal</c>, <c>shutdown</c> or <c>{shutdown,Term}</c>.</item>
</list>
</item>
<item>
@@ -181,8 +184,16 @@ init(...) ->
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>
+ shutdown. It is also allowed to set it to <c>infinity</c>, if the
+ child process is a worker.</item>
</list>
+ <warning>
+ <p>Be careful by setting the <c>Shutdown</c> strategy to
+ <c>infinity</c> when the child process is a worker. Because, in this
+ situation, the termination of the supervision tree depends on the
+ child process, it must be implemented in a safe way and its cleanup
+ procedure must always return.</p>
+ </warning>
</item>
<item>
<p><c>Type</c> specifies if the child process is a supervisor or
@@ -341,6 +352,10 @@ call:start_link(id1)</code>
supervisor:terminate_child(Sup, Pid)</code>
<p>where <c>Sup</c> is the pid, or name, of the supervisor and
<c>Pid</c> is the pid of the child.</p>
+ <p>Because a <c>simple_one_for_one</c> supervisor could have many children,
+ it shuts them all down at same time. So, order in which they are stopped is
+ not defined. For the same reason, it could have an overhead with regards to
+ the <c>Shutdown</c> strategy.</p>
</section>
<section>