aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/design_principles/applications.xml
diff options
context:
space:
mode:
Diffstat (limited to 'system/doc/design_principles/applications.xml')
-rw-r--r--system/doc/design_principles/applications.xml378
1 files changed, 378 insertions, 0 deletions
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>
+