[Erlang Systems]

1 Overview of Design Principles

Systems, or complete products, are made from a number of Applications. Applications provide the basic packaging mechanism for delivering systems. Applications are designed to be "weakly coupled" and it is often possible to make systems by combining existing applications with your own special purpose applications. New applications should be designed to be self sufficient, so they can be added to the existing base of applications and offered to future users of the system.

Examples of existing applications are mnesia, which has everything needed for programming database services, and the gs graphics system for building graphical user interfaces.

Applications are specified in terms of resources. Resources include modules, registered names, processes, and things like dependencies on other applications.

Applications must obey certain laws and must follow certain protocols so that they present a uniform interface to the Erlang runtime system. For example, they must be written so that the code can be changed without stopping the system.

The easiest way to program a new application is to make use of the behaviours which are included in the system. A behaviour is a "pattern of design" which can be used to build an application. Applications which are programmed with the standard behaviours automatically follow the required protocols. Behaviours are explained in the next section of this chapter.

The most common way of programming an Erlang application is to start with a supervision tree. A supervision tree is a hierarchical tree of processes used to program fault-tolerant systems. The higher nodes in the supervision tree are called supervisors. They monitor the lower nodes, which are called workers, and detect when failures occur in the lower nodes.

Worker nodes actually perform computations. They do the work, the supervisors only check the status of the work and restart them if things go wrong. This supervision principle makes it possible to design and program fault-tolerant software. Worker nodes should also be programmed using behaviours, but this depends on what the worker nodes have to do.

If an application is written without the help of the behaviour modules, then the programmer must ensure that the application follows the required protocols. The following two modules are provided to help program applications which do not make use of the standard behaviors:

Both sys and supervisor_bridge are intended for somewhat specialized usage and require detailed knowledge of the Erlang/OTP design principles.

When writing code that is called by the standard behaviours, the programmer can call functions in the standard libraries. The libraries provide a rich and growing set of modules which contain commonly used library functions, such as lists, strings, ordsets, dict, and file.

1.1 Behaviours

Behaviours are formalizations of "design patterns" which can be used to program certain common problems.

Concurrent systems can be programmed by combining ideas and code from a small number of design patterns. Each design pattern, which we call a behaviour, solves a particular problem.

The standard behaviours which are included with the system are:

Behaviours are implemented as callback modules. A callback module must export a specific set of functions, which are then called by the system as the behaviour process executes.

All modules which make use of behaviours should start as follows:

-module(xx).
-behaviour(yy).
...

This means that the module xx has the behaviour yy. In the following declaration, the module disk_alloc has behaviour gen_server

-module(disk_alloc).
-behaviour(gen_server).
...

In a following section, titled Servers, the following type of statements are used (see also the Reference Manual, stdlib, the module gen_server):

Module:init(Args) -> {ok, State} | {ok, State, Timeout}|
                        ignore | {stop, StopReason}
   ...   
Module:handle_call(Request, From, State) -> CallReply
   ...

Here Module is the name of the callback module. In the previous example, this is the module disk_alloc, and disk_alloc must export init/1 and handle_call/3 for example.

Read the section Servers in this chapter, which explains the philosophy of the client-server behaviour. This section should be read in conjunction with the Reference Manual, stdlib, module gen_server, which describes the callback API in greater detail.

It is sometimes possible to write a program which does not make use of the application and behaviour mechanisms. Such programs 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.

Programmers will find it easy to read and understand the code produced by others who are familiar with the application architecture and standard behaviours. Ad hoc programming structures, while possibly more efficient, are always more difficult to understand.


Copyright © 1991-2001 Ericsson Utvecklings AB