Erlang logo
User's Guide
PDF
Top

OTP Design Principles
User's Guide
Version 7.2


Expand All
Contract All

Chapters

7 Applications

This section is to be read with the app(4) and application(3) manual pages in Kernel.

7.1  Application Concept

When you have written code implementing some specific functionality you 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 also be reused in other systems.

To do this, create an application callback module, and describe how the application is to be started and stopped.

Then, an application specification is needed, which is put in an application resource file. Among other things, this file specifies which modules the application consists of and the name of the callback module.

If you 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, that is, 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 is to create the supervision tree by starting the top supervisor. It is expected to return the pid of the top supervisor and an optional term, State, which defaults to []. This term is passed as is to stop.
  • StartType is usually the atom normal. It has other values only in the case of a takeover or failover, see Distributed Applications.
  • StartArgs is defined by the key mod in the application resource file.
  • stop/1 is called after the application has been stopped and is to do any necessary cleaning up. 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 Supervisor Behaviour:

-module(ch_app).
-behaviour(application).

-export([start/2, stop/1]).

start(_Type, _Args) ->
    ch_sup:start_link().

stop(_State) ->
    ok.

A library application that cannot be started or stopped, does not need any application callback module.

7.3  Application Resource File

To define an application, an application specification is created, which is put in an application resource file, or in short an .app file:

{application, Application, [Opt1,...,OptN]}.
  • Application, an atom, is the name of the application. The file must be named Application.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 application libapp looks as follows:

{application, libapp, []}.

The contents of a minimal .app file ch_app.app for a supervision tree application like ch_app looks as follows:

{application, ch_app,
 [{mod, {ch_app,[]}}]}.

The key mod defines the callback module and start argument of the application, in this case ch_app and [], respectively. This means that the following is called when the application is to be started:

ch_app:start(normal, [])

The following is called when the application is stopped.

ch_app:stop([])

When using systools, the Erlang/OTP tools for packaging code (see Section Releases), the keys description, vsn, modules, registered, and applications are also to 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 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 that must be started before this application is started. systools uses this list to generate correct boot scripts. Defaults to []. Notice that all applications have dependencies to at least Kernel and STDLIB.
Note

For details about the syntax and contents of the application resource file, see the app manual page in Kernel.

7.4  Directory Structure

When packaging code using systools, the code for each application is placed in a separate directory, lib/Application-Vsn, where Vsn is the version number.

This can be useful to know, even if systools is not used, since Erlang/OTP is packaged according to the OTP principles and thus comes with this directory structure. The code server (see the code(3) manual page in Kernel) automatically uses code from the directory with the highest version number, if more than one version of an application is present.

The application directory structure can also be used in the development environment. The version number can then be omitted from the name.

The application directory has the following sub-directories:

  • src - Contains the Erlang source code.
  • ebin - Contains the Erlang object code, the beam files. The .app file is also placed here.
  • priv - Used for application specific files. For example, C executables are placed here. The function code:priv_dir/1 is to 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 interacted through the functions in the module application, see the application(3) manual page in Kernel. 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"}]
Note

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 first loads it using application:load/1. It checks the value of the applications key, to ensure that all applications that are to 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 the mod key in the .app file.

An application is stopped, but not unloaded, by calling:

7> application:stop(ch_app).
ok

The application master stops the application by telling the top supervisor to shut down. The top supervisor tells all its child processes to shut down, and so on; 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 the mod 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 key env 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"}]}
 ]}.

Par is to be an atom. Val is any term. The application can retrieve the value of a configuration parameter by calling application:get_env(App, Par) or a number of similar functions, see the application(3) manual page in Kernel.

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 .app file can be overridden by values in a system configuration file. This is a file that contains configuration parameters for relevant applications:

[{Application1, [{Par11,Val11},...]},
 ...,
 {ApplicationN, [{ParN1,ValN1},...]}].

The system configuration is to be called Name.config and Erlang is to be started with the command-line argument -config Name. For details, see the config(4) manual page in Kernel.

Example:

A file test.config is created with the following contents:

[{ch_app, [{file, "testlog"}]}].

The value of file overrides the value of file as defined in the .app file:

% 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"}

If release handling is used, exactly one system configuration file is to be used and that file is to be called sys.config.

The values in the .app file and the values in a system configuration file can be overridden directly from the command line:

% erl -ApplName Par1 Val1 ... ParN ValN

Example:

% 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 Start Types

A start type is defined when starting the application:

application:start(Application, Type)

application:start(Application) is the same as calling application:start(Application, temporary). The type can also be permanent or transient:

  • 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 than normal, all other applications and the runtime system are also terminated.
  • If a temporary application terminates, this is reported but no other applications are terminated.

An application can always be stopped explicitly by calling application:stop/1. Regardless of the mode, no other applications are affected.

The transient mode is of little practical use, since when a supervision tree terminates, the reason is set to shutdown, not normal.