7 Applications
This chapter should be read in conjunction with
app(4)
andapplication(3)
.7.1 Application Concept
When we have written code implementing some specific functionality, we might want to make the code into an application, that is a component that can be started and stopped as a unit, and which can be re-used in other systems as well.
To do this, we create an application callback module, where we describe how the application should be started and stopped.
Then, an application specification is needed, which is put in an application resource file. Among other things, we specify which modules the application consists of and the name of the callback module.
If we use
systools
, the Erlang/OTP tools for packaging code (see Releases), the code for each application is placed in a separate directory following a pre-defined directory structure.7.2 Application Callback Module
How to start and stop the code for the application, i.e. the supervision tree, is described by two callback functions:
start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State} stop(State)
start
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 termState
, which defaults to []. This term is passed as-is tostop
.
StartType
is usually the atomnormal
. It has other values only in the case of a takeover or failover, see Distributed Applications.StartArgs
is defined by the keymod
in the application resource file.
stop/1
is called after 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 Starting and Stopping Applications.Example of an application callback module for packaging the supervision tree from the Supervisor chapter:
-module(ch_app). -behaviour(application). -export([start/2, stop/1]). start(_Type, _Args) -> ch_sup:start_link(). stop(_State) -> ok.A library application, which can not be started or stopped, does not need any application callback module.
7.3 Application Resource File
To define an application, we create an application specification which is put in an application resource file, or in short
.app
file:{application, Application, [Opt1,...,OptN]}.
Application
, an atom, is the name of the application. The file must be namedApplication.app
.Each
Opt
is a tuple{Key, Value}
which define a certain property of the application. All keys are optional. Default values are used for any omitted keys.The contents of a minimal
.app
file for a library applicationlibapp
looks like this:{application, libapp, []}.The contents of a minimal
.app
filech_app.app
for a supervision tree application likech_app
looks like this:{application, ch_app, [{mod, {ch_app,[]}}]}.The key
mod
defines the callback module and start argument of the application, in this casech_app
and [], respectively. This means thatch_app:start(normal, [])will be called when the application should be started and
ch_app:stop([])will be called when the application has been stopped.
When using
systools
, the Erlang/OTP tools for packaging code (see Releases), the keysdescription
,vsn
,modules
,registered
andapplications
should also be specified:{application, ch_app, [{description, "Channel allocator"}, {vsn, "1"}, {modules, [ch_app, ch_sup, ch3]}, {registered, [ch3]}, {applications, [kernel, stdlib, sasl]}, {mod, {ch_app,[]}} ]}.
description
- A short description, a string. Defaults to "".
vsn
- Version number, a string. Defaults to "".
modules
- All modules introduced by this application.
systools
uses this list when generating boot scripts and tar files. A module must be defined in one and only one application. Defaults to [].registered
- All names of registered processes in the application.
systools
uses this list to detect name clashes between applications. Defaults to [].applications
- All applications which must be started before this application is started.
systools
uses this list to generate correct boot scripts. Defaults to [], but note that all applications have dependencies to at leastkernel
andstdlib
.The syntax and contents of of the application resource file are described in detail in
app(4)
.7.4 Directory Structure
When packaging code using
systools
, the code for each application is placed in a separate directorylib/Application-Vsn
, whereVsn
is the version number.This may be useful to know, even if
systools
is not used, since Erlang/OTP itself is packaged according to the OTP principles and thus comes with this directory structure. The code server (seecode(3)
) will automatically use code from the directory with the highest version number, if there are more than one version of an application present.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.
The application directory have the following sub-directories:
src
ebin
priv
include
src
- Contains the Erlang source code. If source code is written in several different languages, a sub-directory with the name
e_src
can be created below thesrc
directory to store the Erlang source code.ebin
- Contains the Erlang object code, the
beam
files. The application resource file is also placed here.priv
- Used for application specific files. For example, C executables are placed here. The function
code:priv_dir/1
should be used to access this directory.include
- Used for include files.
7.5 Application Controller
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 application controller process, registered as
application_controller
.All operations on applications are coordinated by the application controller. It is interfaced through the functions in the module
application
, seeapplication(3)
. In particular, applications can be loaded, unloaded, started and stopped.7.6 Loading and Unloading Applications
Before an application can be started, it must be loaded. The application controller reads and stores the information from the
.app
file.1> application:load(ch_app). ok 2> application:loaded_applications(). [{kernel,"ERTS CXC 138 10","2.8.1.3"}, {stdlib,"ERTS CXC 138 10","1.11.4.3"}, {ch_app,"Channel allocator","1"}]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.
3> application:unload(ch_app). ok 4> application:loaded_applications(). [{kernel,"ERTS CXC 138 10","2.8.1.3"}, {stdlib,"ERTS CXC 138 10","1.11.4.3"}]
Loading/unloading an application does not load/unload the code used by the application. Code loading is done the usual way.
7.7 Starting and Stopping Applications
An application is started by calling:
5> application:start(ch_app). ok 6> application:which_applications(). [{kernel,"ERTS CXC 138 10","2.8.1.3"}, {stdlib,"ERTS CXC 138 10","1.11.4.3"}, {ch_app,"Channel allocator","1"}]If the application is not already loaded, the application controller will first load it similar to calling
application:load/1
. It will check the value of theapplications
key, to ensure that all applications that should be started before this application are running.The application controller then creates an application master 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
start/2
in the module, and with the start argument, defined by themod
key in the.app
file.An application is stopped, but not unloaded, by calling:
7> application:stop(ch_app). okThe 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
stop/1
in the module defined by themod
key.7.8 Configuring an Application
An application can be configured using configuration parameters. These are a list of
{Par, Val}
tuples specified by a keyenv
in the.app
file.{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"}]} ]}.The application can retrieve the value of a configuration parameter by calling
application:get_env(App, Par)
or a number of similar functions, seeapplication(3)
.Example:
% erl Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] Eshell V5.2.3.6 (abort with ^G) 1> application:start(ch_app). ok 2> application:get_env(ch_app, file). {ok,"/usr/local/log"}The values in the application resource file can be overridden by values in a system configuration file, see
config(4)
. The command line argument-config Name
tells the system to use data in the system configuration fileName.config
.The system configuration file should contain a list with one element for each application, a tuple
{Application, [{Par1,Val1},...,{ParN,ValN}]}
.For example, a file
test.config
could be created with the following contents:[{ch_app, [{file, "testlog"}]}].Example:
% erl -config test Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] Eshell V5.2.3.6 (abort with ^G) 1> application:start(ch_app). ok 2> application:get_env(ch_app, file). {ok,"testlog"}The values in the application resource file, as well as the values in a system configuration file, can be overridden directly from the command line:
% erl -ApplName Par1 Val1 ... ParN ValNExample:
% erl -ch_app file '"testlog"' Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] Eshell V5.2.3.6 (abort with ^G) 1> application:start(ch_app). ok 2> application:get_env(ch_app, file). {ok,"testlog"}7.9 Application Modes
An application is started in one of three modes. The mode is defined when starting the application using
application:start(Application, Mode)
and specifies what happens if the application terminates.
application:start(Application)
is the same as callingapplication:start(Application, temporary)
. The mode can also bepermanent
ortransient
.
- If a permanent application terminates, all other applications and the runtime system are also terminated.
- If a transient application terminates with reason
normal
, this is reported but no other applications are terminated. If a transient application terminates abnormally, that is with any other reason thannormal
, all other applications and the runtime system are also terminated.
- If a temporary application terminates, this is reported but no other applications are terminated.
It is always possible to stop an application explicitly by calling
application:stop/1
. Regardless of the mode, no other applications will be affected.Note that transient mode is of little practical use, since when a supervision tree terminates, the reason is set to
shutdown
, notnormal
.