Sophie

Sophie

distrib > Fedora > 17 > i386 > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 7

erlang-doc-R15B-03.3.fc17.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../otp_doc.css" type="text/css">
<title>Erlang -- Overview</title>
</head>
<body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container">
<script id="js" type="text/javascript" language="JavaScript" src="../js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript">
            <!--
              function getWinHeight() {
                var myHeight = 0;
                if( typeof( window.innerHeight ) == 'number' ) {
                  //Non-IE
                  myHeight = window.innerHeight;
                } else if( document.documentElement && ( document.documentElement.clientWidth ||
                                                         document.documentElement.clientHeight ) ) {
                  //IE 6+ in 'standards compliant mode'
                  myHeight = document.documentElement.clientHeight;
                } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
                  //IE 4 compatible
                  myHeight = document.body.clientHeight;
                }
                return myHeight;
              }

              function setscrollpos() {
                var objf=document.getElementById('loadscrollpos');
                 document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2;
              }

              function addEvent(obj, evType, fn){
                if (obj.addEventListener){
                obj.addEventListener(evType, fn, true);
                return true;
              } else if (obj.attachEvent){
                var r = obj.attachEvent("on"+evType, fn);
                return r;
              } else {
                return false;
              }
             }

             addEvent(window, 'load', setscrollpos);

             //--></script><div id="leftnav"><div class="innertube">
<img alt="Erlang logo" src="../erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="../pdf/otp-system-documentation-5.9.3.1.pdf">PDF</a><br><a href="../index.html">Top</a></small><p><strong>OTP Design Principles</strong><br><strong>User's Guide</strong><br><small>Version 5.9.3.1</small></p>
<br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Chapters</strong></small></p>
<ul class="flipMenu" imagepath="../js/flipmenu">
<li id="loadscrollpos" title="Overview" expanded="true">Overview<ul>
<li><a href="des_princ.html">
              Top of chapter
            </a></li>
<li title="Supervision Trees"><a href="des_princ.html#id65609">Supervision Trees</a></li>
<li title="Behaviours"><a href="des_princ.html#id59741">Behaviours</a></li>
<li title="Applications"><a href="des_princ.html#id66345">Applications</a></li>
<li title="Releases"><a href="des_princ.html#id61095">Releases</a></li>
<li title="Release Handling"><a href="des_princ.html#id60860">Release Handling</a></li>
</ul>
</li>
<li id="no" title="Gen_Server Behaviour" expanded="false">Gen_Server Behaviour<ul>
<li><a href="gen_server_concepts.html">
              Top of chapter
            </a></li>
<li title="Client-Server Principles"><a href="gen_server_concepts.html#id64192">Client-Server Principles</a></li>
<li title="Example"><a href="gen_server_concepts.html#id61515">Example</a></li>
<li title="Starting a Gen_Server"><a href="gen_server_concepts.html#id67798">Starting a Gen_Server</a></li>
<li title="Synchronous Requests - Call"><a href="gen_server_concepts.html#id66815">Synchronous Requests - Call</a></li>
<li title="Asynchronous Requests - Cast"><a href="gen_server_concepts.html#id62843">Asynchronous Requests - Cast</a></li>
<li title="Stopping"><a href="gen_server_concepts.html#id67345">Stopping</a></li>
<li title="Handling Other Messages"><a href="gen_server_concepts.html#id67435">Handling Other Messages</a></li>
</ul>
</li>
<li id="no" title="Gen_Fsm Behaviour" expanded="false">Gen_Fsm Behaviour<ul>
<li><a href="fsm.html">
              Top of chapter
            </a></li>
<li title="Finite State Machines"><a href="fsm.html#id68991">Finite State Machines</a></li>
<li title="Example"><a href="fsm.html#id69046">Example</a></li>
<li title="Starting a Gen_Fsm"><a href="fsm.html#id69093">Starting a Gen_Fsm</a></li>
<li title="Notifying About Events"><a href="fsm.html#id69273">Notifying About Events</a></li>
<li title="Timeouts"><a href="fsm.html#id69352">Timeouts</a></li>
<li title="All State Events"><a href="fsm.html#id69391">All State Events</a></li>
<li title="Stopping"><a href="fsm.html#id69423">Stopping</a></li>
<li title="Handling Other Messages"><a href="fsm.html#id69514">Handling Other Messages</a></li>
</ul>
</li>
<li id="no" title="Gen_Event Behaviour" expanded="false">Gen_Event Behaviour<ul>
<li><a href="events.html">
              Top of chapter
            </a></li>
<li title="Event Handling Principles"><a href="events.html#id69613">Event Handling Principles</a></li>
<li title="Example"><a href="events.html#id69665">Example</a></li>
<li title="Starting an Event Manager"><a href="events.html#id69706">Starting an Event Manager</a></li>
<li title="Adding an Event Handler"><a href="events.html#id70832">Adding an Event Handler</a></li>
<li title="Notifying About Events"><a href="events.html#id70916">Notifying About Events</a></li>
<li title="Deleting an Event Handler"><a href="events.html#id70987">Deleting an Event Handler</a></li>
<li title="Stopping"><a href="events.html#id71062">Stopping</a></li>
<li title="Handling Other Messages"><a href="events.html#id71116">Handling Other Messages</a></li>
</ul>
</li>
<li id="no" title="Supervisor Behaviour" expanded="false">Supervisor Behaviour<ul>
<li><a href="sup_princ.html">
              Top of chapter
            </a></li>
<li title="Supervision Principles"><a href="sup_princ.html#id71210">Supervision Principles</a></li>
<li title="Example"><a href="sup_princ.html#id71235">Example</a></li>
<li title="Restart Strategy"><a href="sup_princ.html#id71306">Restart Strategy</a></li>
<li title="Maximum Restart Frequency"><a href="sup_princ.html#id71384">Maximum Restart Frequency</a></li>
<li title="Child Specification"><a href="sup_princ.html#id71906">Child Specification</a></li>
<li title="Starting a Supervisor"><a href="sup_princ.html#id72235">Starting a Supervisor</a></li>
<li title="Adding a Child Process"><a href="sup_princ.html#id72349">Adding a Child Process</a></li>
<li title="Stopping a Child Process"><a href="sup_princ.html#id72393">Stopping a Child Process</a></li>
<li title="Simple-One-For-One Supervisors"><a href="sup_princ.html#id72443">Simple-One-For-One Supervisors</a></li>
<li title="Stopping"><a href="sup_princ.html#id72567">Stopping</a></li>
</ul>
</li>
<li id="no" title="Sys and Proc_Lib" expanded="false">Sys and Proc_Lib<ul>
<li><a href="spec_proc.html">
              Top of chapter
            </a></li>
<li title="Simple Debugging"><a href="spec_proc.html#id72665">Simple Debugging</a></li>
<li title="Special Processes"><a href="spec_proc.html#id72749">Special Processes</a></li>
<li title="User-Defined Behaviours"><a href="spec_proc.html#id73359">User-Defined Behaviours</a></li>
</ul>
</li>
<li id="no" title="Applications" expanded="false">Applications<ul>
<li><a href="applications.html">
              Top of chapter
            </a></li>
<li title="Application Concept"><a href="applications.html#id73539">Application Concept</a></li>
<li title="Application Callback Module"><a href="applications.html#id73606">Application Callback Module</a></li>
<li title="Application Resource File"><a href="applications.html#id73720">Application Resource File</a></li>
<li title="Directory Structure"><a href="applications.html#id73969">Directory Structure</a></li>
<li title="Application Controller"><a href="applications.html#id74095">Application Controller</a></li>
<li title="Loading and Unloading Applications"><a href="applications.html#id74128">Loading and Unloading Applications</a></li>
<li title="Starting and Stopping Applications"><a href="applications.html#id74190">Starting and Stopping Applications</a></li>
<li title="Configuring an Application"><a href="applications.html#id74278">Configuring an Application</a></li>
<li title="Application Start Types"><a href="applications.html#id74477">Application Start Types</a></li>
</ul>
</li>
<li id="no" title="Included Applications" expanded="false">Included Applications<ul>
<li><a href="included_applications.html">
              Top of chapter
            </a></li>
<li title="Definition"><a href="included_applications.html#id74617">Definition</a></li>
<li title="Specifying Included Applications"><a href="included_applications.html#id74682">Specifying Included Applications</a></li>
<li title="Synchronizing Processes During Startup"><a href="included_applications.html#id74708">Synchronizing Processes During Startup</a></li>
</ul>
</li>
<li id="no" title="Distributed Applications" expanded="false">Distributed Applications<ul>
<li><a href="distributed_applications.html">
              Top of chapter
            </a></li>
<li title="Definition"><a href="distributed_applications.html#id74921">Definition</a></li>
<li title="Specifying Distributed Applications"><a href="distributed_applications.html#id74957">Specifying Distributed Applications</a></li>
<li title="Starting and Stopping Distributed Applications"><a href="distributed_applications.html#id75164">Starting and Stopping Distributed Applications</a></li>
<li title="Failover"><a href="distributed_applications.html#id75266">Failover</a></li>
<li title="Takeover"><a href="distributed_applications.html#id75408">Takeover</a></li>
</ul>
</li>
<li id="no" title="Releases" expanded="false">Releases<ul>
<li><a href="release_structure.html">
              Top of chapter
            </a></li>
<li title="Release Concept"><a href="release_structure.html#id75603">Release Concept</a></li>
<li title="Release Resource File"><a href="release_structure.html#id75656">Release Resource File</a></li>
<li title="Generating Boot Scripts"><a href="release_structure.html#id75803">Generating Boot Scripts</a></li>
<li title="Creating a Release Package"><a href="release_structure.html#id75897">Creating a Release Package</a></li>
<li title="Directory Structure"><a href="release_structure.html#id76046">Directory Structure</a></li>
</ul>
</li>
<li id="no" title="Release Handling" expanded="false">Release Handling<ul>
<li><a href="release_handling.html">
              Top of chapter
            </a></li>
<li title="Release Handling Principles"><a href="release_handling.html#id76299">Release Handling Principles</a></li>
<li title="Requirements"><a href="release_handling.html#id76543">Requirements</a></li>
<li title="Distributed Systems"><a href="release_handling.html#id76636">Distributed Systems</a></li>
<li title="Release Handling Instructions"><a href="release_handling.html#id76663">Release Handling Instructions</a></li>
<li title="Application Upgrade File"><a href="release_handling.html#id77177">Application Upgrade File</a></li>
<li title="Release Upgrade File"><a href="release_handling.html#id77359">Release Upgrade File</a></li>
<li title="Installing a Release"><a href="release_handling.html#id77515">Installing a Release</a></li>
<li title="Updating Application Specifications"><a href="release_handling.html#id77986">Updating Application Specifications</a></li>
</ul>
</li>
<li id="no" title="Appup Cookbook" expanded="false">Appup Cookbook<ul>
<li><a href="appup_cookbook.html">
              Top of chapter
            </a></li>
<li title="Changing a Functional Module"><a href="appup_cookbook.html#id78170">Changing a Functional Module</a></li>
<li title="Changing a Residence Module"><a href="appup_cookbook.html#id78193">Changing a Residence Module</a></li>
<li title="Changing a Callback Module"><a href="appup_cookbook.html#id78232">Changing a Callback Module</a></li>
<li title="Changing Internal State"><a href="appup_cookbook.html#id78283">Changing Internal State</a></li>
<li title="Module Dependencies"><a href="appup_cookbook.html#id78417">Module Dependencies</a></li>
<li title="Changing Code For a Special Process"><a href="appup_cookbook.html#id78588">Changing Code For a Special Process</a></li>
<li title="Changing a Supervisor"><a href="appup_cookbook.html#id78755">Changing a Supervisor</a></li>
<li title="Adding or Deleting a Module"><a href="appup_cookbook.html#id79000">Adding or Deleting a Module</a></li>
<li title="Starting or Terminating a Process"><a href="appup_cookbook.html#id79026">Starting or Terminating a Process</a></li>
<li title="Adding or Removing an Application"><a href="appup_cookbook.html#id79044">Adding or Removing an Application</a></li>
<li title="Restarting an Application"><a href="appup_cookbook.html#id79075">Restarting an Application</a></li>
<li title="Changing an Application Specification"><a href="appup_cookbook.html#id79117">Changing an Application Specification</a></li>
<li title="Changing Application Configuration"><a href="appup_cookbook.html#id79141">Changing Application Configuration</a></li>
<li title="Changing Included Applications"><a href="appup_cookbook.html#id79174">Changing Included Applications</a></li>
<li title="Changing Non-Erlang Code"><a href="appup_cookbook.html#id79414">Changing Non-Erlang Code</a></li>
<li title="Emulator Restart and Upgrade"><a href="appup_cookbook.html#id79499">Emulator Restart and Upgrade</a></li>
<li title="Emulator Upgrade from pre OTP R15"><a href="appup_cookbook.html#id79575">Emulator Upgrade from pre OTP R15</a></li>
</ul>
</li>
</ul>
</div></div>
<div id="content">
<div class="innertube">
<h1>1 Overview</h1>
  
  <p>The <strong>OTP Design Principles</strong> is a set of principles for how
    to structure Erlang code in terms of processes, modules and
    directories.</p>

  <h3><a name="id65609">1.1 
        Supervision Trees</a></h3>
    
    <p>A basic concept in Erlang/OTP is the <strong>supervision tree</strong>.
      This is a process structuring model based on the idea of
      <strong>workers</strong> and <strong>supervisors</strong>.</p>
    <ul>
      <li>Workers are processes which perform computations, that is,
       they do the actual work.</li>
      <li>Supervisors are processes which monitor the behaviour of
       workers. A supervisor can restart a worker if something goes
       wrong.</li>
      <li>The supervision tree is a hierarchical arrangement of
       code into supervisors and workers, making it possible to
       design and program fault-tolerant software.</li>
    </ul>
    <a name="sup6"></a>
    <img alt="IMAGE MISSING" src="../design_principles/sup6.gif"><br>
      <em>Figure
        1.1:
         
        Supervision Tree</em>
    
    <p>In the figure above, square boxes represents supervisors and
      circles represent workers.</p>
  

  <h3><a name="id59741">1.2 
        Behaviours</a></h3>
    
    <p>In a supervision tree, many of the processes have similar
      structures, they follow similar patterns. For example,
      the supervisors are very similar in structure. The only difference
      between them is which child processes they supervise. Also, many
      of the workers are servers in a server-client relation, finite
      state machines, or event handlers such as error loggers.</p>
    <p><strong>Behaviours</strong> are formalizations of these common patterns.
      The idea is to divide the code for a process in a generic part
      (a behaviour module) and a specific part (a <strong>callback module</strong>).</p>
    <p>The behaviour module is part of Erlang/OTP. To implement a
      process such as a supervisor, the user only has to implement
      the callback module which should export a pre-defined set of
      functions, the <strong>callback functions</strong>.</p>
    <p>An example to illustrate how code can be divided into a generic
      and a specific part: Consider the following code (written in
      plain Erlang) for a simple server, which keeps track of a number
      of "channels". Other processes can allocate and free the channels
      by calling the functions <span class="code">alloc/0</span> and <span class="code">free/1</span>,
      respectively.</p>
    <a name="ch1"></a>
    <div class="example"><pre>
-module(ch1).
-export([start/0]).
-export([alloc/0, free/1]).
-export([init/0]).

start() -&gt;
    spawn(ch1, init, []).

alloc() -&gt;
    ch1 ! {self(), alloc},
    receive
        {ch1, Res} -&gt;
            Res
    end.

free(Ch) -&gt;
    ch1 ! {free, Ch},
    ok.

init() -&gt;
    register(ch1, self()),
    Chs = channels(),
    loop(Chs).

loop(Chs) -&gt;
    receive
        {From, alloc} -&gt;
            {Ch, Chs2} = alloc(Chs),
            From ! {ch1, Ch},
            loop(Chs2);
        {free, Ch} -&gt;
            Chs2 = free(Ch, Chs),
            loop(Chs2)
    end.</pre></div>
    <p>The code for the server can be rewritten into a generic part
      <span class="code">server.erl</span>:</p>
    <div class="example"><pre>
-module(server).
-export([start/1]).
-export([call/2, cast/2]).
-export([init/1]).

start(Mod) -&gt;
    spawn(server, init, [Mod]).

call(Name, Req) -&gt;
    Name ! {call, self(), Req},
    receive
        {Name, Res} -&gt;
            Res
    end.

cast(Name, Req) -&gt;
    Name ! {cast, Req},
    ok.

init(Mod) -&gt;
    register(Mod, self()),
    State = Mod:init(),
    loop(Mod, State).

loop(Mod, State) -&gt;
    receive
        {call, From, Req} -&gt;
            {Res, State2} = Mod:handle_call(Req, State),
            From ! {Mod, Res},
            loop(Mod, State2);
        {cast, Req} -&gt;
            State2 = Mod:handle_cast(Req, State),
            loop(Mod, State2)
    end.</pre></div>
    <p>and a callback module <span class="code">ch2.erl</span>:</p>
    <div class="example"><pre>
-module(ch2).
-export([start/0]).
-export([alloc/0, free/1]).
-export([init/0, handle_call/2, handle_cast/2]).

start() -&gt;
    server:start(ch2).

alloc() -&gt;
    server:call(ch2, alloc).

free(Ch) -&gt;
    server:cast(ch2, {free, Ch}).

init() -&gt;
    channels().

handle_call(alloc, Chs) -&gt;
    alloc(Chs). % =&gt; {Ch,Chs2}

handle_cast({free, Ch}, Chs) -&gt;
    free(Ch, Chs). % =&gt; Chs2</pre></div>
    <p>Note the following:</p>
    <ul>
      <li>The code in <span class="code">server</span> can be re-used to build many
       different servers.</li>
      <li>The name of the server, in this example the atom
      <span class="code">ch2</span>, is hidden from the users of the client functions.
       This means the name can be changed without affecting them.</li>
      <li>The protcol (messages sent to and received from the server)
       is hidden as well. This is good programming practice and allows
       us to change the protocol without making changes to code using
       the interface functions.</li>
      <li>We can extend the functionality of <span class="code">server</span>, without
       having to change <span class="code">ch2</span> or any other callback module.</li>
    </ul>
    <p>(In <span class="code">ch1.erl</span> and <span class="code">ch2.erl</span> above, the implementation
      of <span class="code">channels/0</span>, <span class="code">alloc/1</span> and <span class="code">free/2</span> has been
      intentionally left out, as it is not relevant to the example.
      For completeness, one way to write these functions are given
      below. Note that this is an example only, a realistic
      implementation must be able to handle situations like running out
      of channels to allocate etc.)</p>
    <div class="example"><pre>
channels() -&gt;
   {_Allocated = [], _Free = lists:seq(1,100)}.

alloc({Allocated, [H|T] = _Free}) -&gt;
   {H, {[H|Allocated], T}}.

free(Ch, {Alloc, Free} = Channels) -&gt;
   case lists:member(Ch, Alloc) of
      true -&gt;
         {lists:delete(Ch, Alloc), [Ch|Free]};
      false -&gt;
         Channels
   end.        </pre></div>
    <p>Code written without making use of behaviours 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.</p>
    <p>Using behaviours also makes it easier to read and understand
      code written by other programmers. Ad hoc programming structures,
      while possibly more efficient, are always more difficult to
      understand.</p>
    <p>The module <span class="code">server</span> corresponds, greatly simplified,
      to the Erlang/OTP behaviour <span class="code">gen_server</span>.</p>
    <p>The standard Erlang/OTP behaviours are:</p>
    <dl>
      <dt><strong><span class="bold_code"><a href="gen_server_concepts.html">gen_server</a></span></strong></dt>
      <dd>For implementing the server of a client-server relation.</dd>
      <dt><strong><span class="bold_code"><a href="fsm.html">gen_fsm</a></span></strong></dt>
      <dd>For implementing finite state machines.</dd>
      <dt><strong><span class="bold_code"><a href="events.html">gen_event</a></span></strong></dt>
      <dd>For implementing event handling functionality.</dd>
      <dt><strong><span class="bold_code"><a href="sup_princ.html">supervisor</a></span></strong></dt>
      <dd>For implementing a supervisor in a supervision tree.</dd>
    </dl>
    <p>The compiler understands the module attribute
      <span class="code">-behaviour(Behaviour)</span> and issues warnings about
      missing callback functions. Example:</p>
    <div class="example"><pre>
-module(chs3).
-behaviour(gen_server).
...

3&gt; c(chs3).
./chs3.erl:10: Warning: undefined call-back function handle_call/3
{ok,chs3}</pre></div>
  

  <h3><a name="id66345">1.3 
        Applications</a></h3>
    
    <p>Erlang/OTP comes with a number of components, each implementing
      some specific functionality. Components are with Erlang/OTP
      terminology called <strong>applications</strong>. Examples of Erlang/OTP
      applications are Mnesia, which has everything needed for
      programming database services, and Debugger which is used to
      debug Erlang programs. The minimal system based on Erlang/OTP
      consists of the applications Kernel and STDLIB.</p>
    <p>The application concept applies both to program structure
      (processes) and directory structure (modules).</p>
    <p>The simplest kind of application does not have any processes,
      but consists of a collection of functional modules. Such an
      application is called a <strong>library application</strong>. An example
      of a library application is STDLIB.</p>
    <p>An application with processes is easiest implemented as a
      supervision tree using the standard behaviours.</p>
    <p>How to program applications is described in
      <span class="bold_code"><a href="applications.html">Applications</a></span>.</p>
  

  <h3><a name="id61095">1.4 
        Releases</a></h3>
    
    <p>A <strong>release</strong> is a complete system made out from a subset of
      the Erlang/OTP applications and a set of user-specific
      applications.</p>
    <p>How to program releases is described in
      <span class="bold_code"><a href="release_structure.html">Releases</a></span>.</p>
    <p>How to install a release in a target environment is described
      in the chapter about Target Systems in System Principles.</p>
  

  <h3><a name="id60860">1.5 
        Release Handling</a></h3>
    
    <p><strong>Release handling</strong> is upgrading and downgrading between
      different versions of a release, in a (possibly) running system.
      How to do this is described in
      <span class="bold_code"><a href="release_handling.html">Release Handling</a></span>.</p>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>