Sophie

Sophie

distrib > Fedora > 17 > i386 > media > updates > by-pkgid > 675c8c8167236dfcf8d66da674f931e8 > files > 5

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 -- Appup Cookbook</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="no" title="Overview" expanded="false">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="loadscrollpos" title="Appup Cookbook" expanded="true">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>12 Appup Cookbook</h1>
  
  <p>This chapter contains examples of <span class="code">.appup</span> files for
    typical cases of upgrades/downgrades done in run-time.</p>

  <h3><a name="id78170">12.1 
        Changing a Functional Module</a></h3>
    
    <p>When a change has been made to a functional module, for example
      if a new function has been added or a bug has been corrected,
      simple code replacement is sufficient.</p>
    <p>Example:</p>
    <div class="example"><pre>
{"2",
 [{"1", [{load_module, m}]}],
 [{"1", [{load_module, m}]}]
}.</pre></div>
  

  <h3><a name="id78193">12.2 
        Changing a Residence Module</a></h3>
    
    <p>In a system implemented according to the OTP Design Principles,
      all processes, except system processes and special processes,
      reside in one of the behaviours <span class="code">supervisor</span>,
      <span class="code">gen_server</span>, <span class="code">gen_fsm</span> or <span class="code">gen_event</span>. These
      belong to the STDLIB application and upgrading/downgrading
      normally requires an emulator restart.</p>
    <p>OTP thus provides no support for changing residence modules
      except in the case of <span class="bold_code"><a href="#spec">special processes</a></span>.</p>
  

  <h3><a name="id78232">12.3 
        Changing a Callback Module</a></h3>
    
    <p>A callback module is a functional module, and for code
      extensions simple code replacement is sufficient.</p>
    <p>Example: When adding a function to <span class="code">ch3</span> as described in
      the example in <span class="bold_code"><a href="release_handling.html#appup">Release Handling</a></span>, <span class="code">ch_app.appup</span> looks as follows:</p>
    <div class="example"><pre>
{"2",
 [{"1", [{load_module, ch3}]}],
 [{"1", [{load_module, ch3}]}]
}.</pre></div>
    <p>OTP also supports changing the internal state of behaviour
      processes, see <span class="bold_code"><a href="#int_state">Changing Internal State</a></span> below.</p>
  

  <h3><a name="id78283">12.4 
        Changing Internal State</a></h3>
    <a name="int_state"></a>
    
    <p>In this case, simple code replacement is not sufficient.
      The process must explicitly transform its state using the callback
      function <span class="code">code_change</span> before switching to the new version
      of the callback module. Thus synchronized code replacement is
      used.</p>
    <p>Example: Consider the gen_server <span class="code">ch3</span> from the chapter
      about the <span class="bold_code"><a href="gen_server_concepts.html#ex">gen_server behaviour</a></span>. The internal state is a term <span class="code">Chs</span>
      representing the available channels. Assume we want add a counter
      <span class="code">N</span> which keeps track of the number of <span class="code">alloc</span> requests
      so far. This means we need to change the format to
      <span class="code">{Chs,N}</span>.</p>
    <p>The <span class="code">.appup</span> file could look as follows:</p>
    <div class="example"><pre>
{"2",
 [{"1", [{update, ch3, {advanced, []}}]}],
 [{"1", [{update, ch3, {advanced, []}}]}]
}.</pre></div>
    <p>The third element of the <span class="code">update</span> instruction is a tuple
      <span class="code">{advanced,Extra}</span> which says that the affected processes
      should do a state transformation before loading the new version
      of the module. This is done by the processes calling the callback
      function <span class="code">code_change</span> (see <span class="code">gen_server(3)</span>). The term
      <span class="code">Extra</span>, in this case [], is passed as-is to the function:</p>
    <a name="code_change"></a>
    <div class="example"><pre>
-module(ch3).
...
-export([code_change/3]).
...
code_change({down, _Vsn}, {Chs, N}, _Extra) -&gt;
    {ok, Chs};
code_change(_Vsn, Chs, _Extra) -&gt;
    {ok, {Chs, 0}}.</pre></div>
    <p>The first argument is <span class="code">{down,Vsn}</span> in case of a downgrade,
      or <span class="code">Vsn</span> in case of an upgrade. The term <span class="code">Vsn</span> is
      fetched from the 'original' version of the module, i.e.
      the version we are upgrading from, or downgrading to.</p>
    <p>The version is defined by the module attribute <span class="code">vsn</span>, if
      any. There is no such attribute in <span class="code">ch3</span>, so in this case
      the version is the checksum (a huge integer) of the BEAM file, an
      uninteresting value which is ignored.</p>
    <p>(The other callback functions of <span class="code">ch3</span> need to be modified
      as well and perhaps a new interface function added, this is not
      shown here).</p>
  

  <h3><a name="id78417">12.5 
        Module Dependencies</a></h3>
    
    <p>Assume we extend a module by adding a new interface function, as
      in the example in <span class="bold_code"><a href="release_handling.html#appup">Release Handling</a></span>, where a function <span class="code">available/0</span> is
      added to <span class="code">ch3</span>.</p>
    <p>If we also add a call to this function, say in the module
      <span class="code">m1</span>, a run-time error could occur during release upgrade if
      the new version of <span class="code">m1</span> is loaded first and calls
      <span class="code">ch3:available/0</span> before the new version of <span class="code">ch3</span> is
      loaded.</p>
    <p>Thus, <span class="code">ch3</span> must be loaded before <span class="code">m1</span> is, in
      the upgrade case, and vice versa in the downgrade case. We say
      that <span class="code">m1</span><strong>is dependent on</strong><span class="code">ch3</span>. In a release
      handling instruction, this is expressed by the element
      <span class="code">DepMods</span>:</p>
    <div class="example"><pre>
{load_module, Module, DepMods}
{update, Module, {advanced, Extra}, DepMods}</pre></div>
    <p><span class="code">DepMods</span> is a list of modules, on which <span class="code">Module</span> is
      dependent.</p>
    <p>Example: The module <span class="code">m1</span> in the application <span class="code">myapp</span> is
      dependent on <span class="code">ch3</span> when upgrading from "1" to "2", or
      downgrading from "2" to "1":</p>
    <div class="example"><pre>
myapp.appup:

{"2",
 [{"1", [{load_module, m1, [ch3]}]}],
 [{"1", [{load_module, m1, [ch3]}]}]
}.

ch_app.appup:

{"2",
 [{"1", [{load_module, ch3}]}],
 [{"1", [{load_module, ch3}]}]
}.</pre></div>
    <p>If <span class="code">m1</span> and <span class="code">ch3</span> had belonged to the same application,
      the <span class="code">.appup</span> file could have looked like this:</p>
    <div class="example"><pre>
{"2",
 [{"1",
   [{load_module, ch3},
    {load_module, m1, [ch3]}]}],
 [{"1",
   [{load_module, ch3},
    {load_module, m1, [ch3]}]}]
}.</pre></div>
    <p>Note that it is <span class="code">m1</span> that is dependent on <span class="code">ch3</span> also
      when downgrading. <span class="code">systools</span> knows the difference between
      up- and downgrading and will generate a correct <span class="code">relup</span>,
      where <span class="code">ch3</span> is loaded before <span class="code">m1</span> when upgrading but
      <span class="code">m1</span> is loaded before <span class="code">ch3</span> when downgrading.</p>
  

  <h3><a name="id78588">12.6 
        Changing Code For a Special Process</a></h3>
    <a name="spec"></a>
    
    <p>In this case, simple code replacement is not sufficient.
      When a new version of a residence module for a special process
      is loaded, the process must make a fully qualified call to
      its loop function to switch to the new code. Thus synchronized
      code replacement must be used.</p>
    <div class="note">
<div class="label">Note</div>
<div class="content"><p>
      <p>The name(s) of the user-defined residence module(s) must be
        listed in the <span class="code">Modules</span> part of the child specification
        for the special process, in order for the release handler to
        find the process.</p>
    </p></div>
</div>
    <p>Example. Consider the example <span class="code">ch4</span> from the chapter about
      <span class="bold_code"><a href="spec_proc.html#ex">sys and proc_lib</a></span>.
      When started by a supervisor, the child specification could look
      like this:</p>
    <div class="example"><pre>
{ch4, {ch4, start_link, []},
 permanent, brutal_kill, worker, [ch4]}</pre></div>
    <p>If <span class="code">ch4</span> is part of the application <span class="code">sp_app</span> and a new
      version of the module should be loaded when upgrading from
      version "1" to "2" of this application, <span class="code">sp_app.appup</span> could
      look like this:</p>
    <div class="example"><pre>
{"2",
 [{"1", [{update, ch4, {advanced, []}}]}],
 [{"1", [{update, ch4, {advanced, []}}]}]
}.</pre></div>
    <p>The <span class="code">update</span> instruction must contain the tuple
      <span class="code">{advanced,Extra}</span>. The instruction will make the special
      process call the callback function <span class="code">system_code_change/4</span>, a
      function the user must implement. The term <span class="code">Extra</span>, in this
      case [], is passed as-is to <span class="code">system_code_change/4</span>:</p>
    <div class="example"><pre>
-module(ch4).
...
-export([system_code_change/4]).
...

system_code_change(Chs, _Module, _OldVsn, _Extra) -&gt;
    {ok, Chs}.</pre></div>
    <p>The first argument is the internal state <span class="code">State</span> passed from
      the function <span class="code">sys:handle_system_msg(Request, From, Parent, Module, Deb, State)</span>, called by the special process when
      a system message is received. In <span class="code">ch4</span>, the internal state is
      the set of available channels <span class="code">Chs</span>.</p>
    <p>The second argument is the name of the module (<span class="code">ch4</span>).</p>
    <p>The third argument is <span class="code">Vsn</span> or <span class="code">{down,Vsn}</span> as
      described for
      <span class="bold_code"><a href="#code_change">gen_server:code_change/3</a></span>.</p>
    <p>In this case, all arguments but the first are ignored and
      the function simply returns the internal state again. This is
      enough if the code only has been extended. If we had wanted to
      change the internal state (similar to the example in
      <span class="bold_code"><a href="#int_state">Changing Internal State</a></span>),
      it would have been done in this function and
      <span class="code">{ok,Chs2}</span> returned.</p>
  

  <h3><a name="id78755">12.7 
        Changing a Supervisor</a></h3>
    <a name="sup"></a>
    
    <p>The supervisor behaviour supports changing the internal state,
      i.e. changing restart strategy and maximum restart frequency
      properties, as well as changing existing child specifications.</p>
    <p>Adding and deleting child processes are also possible, but not
      handled automatically. Instructions must be given by in
      the <span class="code">.appup</span> file.</p>

    <h4>Changing Properties</h4>
      
      <p>Since the supervisor should change its internal state,
        synchronized code replacement is required. However,
        a special <span class="code">update</span> instruction must be used.</p>
      <p>The new version of the callback module must be loaded first
        both in the case of upgrade and downgrade. Then the new return
        value of <span class="code">init/1</span> can be checked and the internal state be
        changed accordingly.</p>
      <p>The following <span class="code">upgrade</span> instruction is used for
        supervisors:</p>
      <div class="example"><pre>
{update, Module, supervisor}</pre></div>
      <p>Example: Assume we want to change the restart strategy of
        <span class="code">ch_sup</span> from the <span class="bold_code"><a href="sup_princ.html#ex">Supervisor Behaviour</a></span> chapter from one_for_one to one_for_all.
        We change the callback function <span class="code">init/1</span> in
        <span class="code">ch_sup.erl</span>:</p>
      <div class="example"><pre>
-module(ch_sup).
...

init(_Args) -&gt;
    {ok, {{one_for_all, 1, 60}, ...}}.</pre></div>
      <p>The file <span class="code">ch_app.appup</span>:</p>
      <div class="example"><pre>
{"2",
 [{"1", [{update, ch_sup, supervisor}]}],
 [{"1", [{update, ch_sup, supervisor}]}]
}.</pre></div>
    

    <h4>Changing Child Specifications</h4>
      
      <p>The instruction, and thus the <span class="code">.appup</span> file, when
        changing an existing child specification, is the same as when
        changing properties as described above:</p>
      <div class="example"><pre>
{"2",
 [{"1", [{update, ch_sup, supervisor}]}],
 [{"1", [{update, ch_sup, supervisor}]}]
}.</pre></div>
      <p>The changes do not affect existing child processes. For
        example, changing the start function only specifies how
        the child process should be restarted, if needed later on.</p>
      <p>Note that the id of the child specification cannot be changed.</p>
      <p>Note also that changing the <span class="code">Modules</span> field of the child
        specification may affect the release handling process itself,
        as this field is used to identify which processes are affected
        when doing a synchronized code replacement.</p>
    
    <a name="sup_add"></a>

    <h4>Adding And Deleting Child Processes</h4>
      
      <p>As stated above, changing child specifications does not affect
        existing child processes. New child specifications are
        automatically added, but not deleted. Also, child processes are
        not automatically started or terminated. Instead, this must be
        done explicitly using <span class="code">apply</span> instructions.</p>
      <p>Example: Assume we want to add a new child process <span class="code">m1</span> to
        <span class="code">ch_sup</span> when upgrading <span class="code">ch_app</span> from "1" to "2".
        This means <span class="code">m1</span> should be deleted when downgrading from
        "2" to "1":</p>
      <div class="example"><pre>
{"2",
 [{"1",
   [{update, ch_sup, supervisor},
    {apply, {supervisor, restart_child, [ch_sup, m1]}}
   ]}],
 [{"1",
   [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
    {apply, {supervisor, delete_child, [ch_sup, m1]}},
    {update, ch_sup, supervisor}
   ]}]
}.</pre></div>
      <p>Note that the order of the instructions is important.</p>
      <p>Note also that the supervisor must be registered as
        <span class="code">ch_sup</span> for the script to work. If the supervisor is not
        registered, it cannot be accessed directly from the script.
        Instead a help function that finds the pid of the supervisor
        and calls <span class="code">supervisor:restart_child</span> etc. must be written,
        and it is this function that should be called from the script
        using the <span class="code">apply</span> instruction.</p>
      <p>If the module <span class="code">m1</span> is introduced in version "2" of
        <span class="code">ch_app</span>, it must also be loaded when upgrading and
        deleted when downgrading:</p>
      <div class="example"><pre>
{"2",
 [{"1",
   [{add_module, m1},
    {update, ch_sup, supervisor},
    {apply, {supervisor, restart_child, [ch_sup, m1]}}
   ]}],
 [{"1",
   [{apply, {supervisor, terminate_child, [ch_sup, m1]}},
    {apply, {supervisor, delete_child, [ch_sup, m1]}},
    {update, ch_sup, supervisor},
    {delete_module, m1}
   ]}]
}.</pre></div>
      <p>Note again that the order of the instructions is important.
        When upgrading, <span class="code">m1</span> must be loaded and the supervisor's
        child specification changed, before the new child process can
        be started. When downgrading, the child process must be
        terminated before child specification is changed and the module
        is deleted.</p>
    
  

  <h3><a name="id79000">12.8 
        Adding or Deleting a Module</a></h3>
    
    <p>Example: A new functional module <span class="code">m</span> is added to
      <span class="code">ch_app</span>:</p>
    <div class="example"><pre>
{"2",
 [{"1", [{add_module, m}]}],
 [{"1", [{delete_module, m}]}]</pre></div>
  

  <h3><a name="id79026">12.9 
        Starting or Terminating a Process</a></h3>
    
    <p>In a system structured according to the OTP design principles,
      any process would be a child process belonging to a supervisor,
      see <span class="bold_code"><a href="#sup_add">Adding and Deleting Child Processes</a></span> above.</p>
  

  <h3><a name="id79044">12.10 
        Adding or Removing an Application</a></h3>
    
    <p>When adding or removing an application, no <span class="code">.appup</span> file
      is needed. When generating <span class="code">relup</span>, the <span class="code">.rel</span> files
      are compared and <span class="code">add_application</span> and
      <span class="code">remove_application</span> instructions are added automatically.</p>
  

  <h3><a name="id79075">12.11 
        Restarting an Application</a></h3>
    
    <p>Restarting an application is useful when a change is too
      complicated to be made without restarting the processes, for
      example if the supervisor hierarchy has been restructured.</p>
    <p>Example: When adding a new child <span class="code">m1</span> to <span class="code">ch_sup</span>, as
      in the <span class="bold_code"><a href="#sup_add">example above</a></span>, an
      alternative to updating the supervisor is to restart the entire
      application:</p>
    <div class="example"><pre>
{"2",
 [{"1", [{restart_application, ch_app}]}],
 [{"1", [{restart_application, ch_app}]}]
}.</pre></div>
  

  <h3><a name="id79117">12.12 
        Changing an Application Specification</a></h3>
    <a name="app_spec"></a>
    
    <p>When installing a release, the application specifications are
      automatically updated before evaluating the <span class="code">relup</span> script.
      Hence, no instructions are  needed in the <span class="code">.appup</span> file:</p>
    <div class="example"><pre>
{"2",
 [{"1", []}],
 [{"1", []}]
}.</pre></div>
  

  <h3><a name="id79141">12.13 
        Changing Application Configuration</a></h3>
    
    <p>Changing an application configuration by updating the <span class="code">env</span>
      key in the <span class="code">.app</span> file is an instance of changing an
      application specification, <span class="bold_code"><a href="#app_spec">see above</a></span>.</p>
    <p>Alternatively, application configuration parameters can be
      added or updated in <span class="code">sys.config</span>.</p>
  

  <h3><a name="id79174">12.14 
        Changing Included Applications</a></h3>
    
    <p>The release handling instructions for adding, removing and
      restarting applications apply to primary applications only.
      There are no corresponding instructions for included
      applications. However, since an included application is really a
      supervision tree with a topmost supervisor, started as a child
      process to a supervisor in the including application, a
      <span class="code">relup</span> file can be manually created.</p>
    <p>Example: Assume we have a release containing an application
      <span class="code">prim_app</span> which have a supervisor <span class="code">prim_sup</span> in its
      supervision tree.</p>
    <p>In a new version of the release, our example application
      <span class="code">ch_app</span> should be included in <span class="code">prim_app</span>. That is,
      its topmost supervisor <span class="code">ch_sup</span> should be started as a child
      process to <span class="code">prim_sup</span>.</p>
    <p>1) Edit the code for <span class="code">prim_sup</span>:</p>
    <div class="example"><pre>
init(...) -&gt;
    {ok, {...supervisor flags...,
          [...,
           {ch_sup, {ch_sup,start_link,[]},
            permanent,infinity,supervisor,[ch_sup]},
           ...]}}.</pre></div>
    <p>2) Edit the <span class="code">.app</span> file for <span class="code">prim_app</span>:</p>
    <div class="example"><pre>
{application, prim_app,
 [...,
  {vsn, "2"},
  ...,
  {included_applications, [ch_app]},
  ...
 ]}.</pre></div>
    <p>3) Create a new <span class="code">.rel</span> file, including <span class="code">ch_app</span>:</p>
    <div class="example"><pre>
{release,
 ...,
 [...,
  {prim_app, "2"},
  {ch_app, "1"}]}.</pre></div>

    <h4>Application Restart</h4>
      
      <p>4a) One way to start the included application is to restart
        the entire <span class="code">prim_app</span> application. Normally, we would then
        use the <span class="code">restart_application</span> instruction in
        the <span class="code">.appup</span> file for <span class="code">prim_app</span>.</p>
      <p>However, if we did this and then generated a <span class="code">relup</span> file,
        not only would it contain instructions for restarting (i.e.
        removing and adding) <span class="code">prim_app</span>, it would also contain
        instructions for starting <span class="code">ch_app</span> (and stopping it, in
        the case of downgrade). This is due to the fact that
        <span class="code">ch_app</span> is included in the new <span class="code">.rel</span> file, but not
        in the old one.</p>
      <p>Instead, a correct <span class="code">relup</span> file can be created manually,
        either from scratch or by editing the generated version.
        The instructions for starting/stopping <span class="code">ch_app</span> are
        replaced by instructions for loading/unloading the application:</p>
      <div class="example"><pre>
{"B",
 [{"A",
   [],
   [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
    {load_object_code,{prim_app,"2",[prim_app,prim_sup]}},
    point_of_no_return,
    {apply,{application,stop,[prim_app]}},
    {remove,{prim_app,brutal_purge,brutal_purge}},
    {remove,{prim_sup,brutal_purge,brutal_purge}},
    {purge,[prim_app,prim_sup]},
    {load,{prim_app,brutal_purge,brutal_purge}},
    {load,{prim_sup,brutal_purge,brutal_purge}},
    {load,{ch_sup,brutal_purge,brutal_purge}},
    {load,{ch3,brutal_purge,brutal_purge}},
    {apply,{application,load,[ch_app]}},
    {apply,{application,start,[prim_app,permanent]}}]}],
 [{"A",
   [],
   [{load_object_code,{prim_app,"1",[prim_app,prim_sup]}},
    point_of_no_return,
    {apply,{application,stop,[prim_app]}},
    {apply,{application,unload,[ch_app]}},
    {remove,{ch_sup,brutal_purge,brutal_purge}},
    {remove,{ch3,brutal_purge,brutal_purge}},
    {purge,[ch_sup,ch3]},
    {remove,{prim_app,brutal_purge,brutal_purge}},
    {remove,{prim_sup,brutal_purge,brutal_purge}},
    {purge,[prim_app,prim_sup]},
    {load,{prim_app,brutal_purge,brutal_purge}},
    {load,{prim_sup,brutal_purge,brutal_purge}},
    {apply,{application,start,[prim_app,permanent]}}]}]
}.</pre></div>
    

    <h4>Supervisor Change</h4>
      
      <p>4b) Another way to start the included application (or stop it
        in the case of downgrade) is by combining instructions for
        adding and removing child processes to/from <span class="code">prim_sup</span> with
        instructions for loading/unloading all <span class="code">ch_app</span> code and
        its application specification.</p>
      <p>Again, the <span class="code">relup</span> file is created manually. Either from
        scratch or by editing a generated version. Load all code for
        <span class="code">ch_app</span> first, and also load the application
        specification, before <span class="code">prim_sup</span> is updated. When
        downgrading, <span class="code">prim_sup</span> should be updated first, before
        the code for <span class="code">ch_app</span> and its application specification
        are unloaded.</p>
      <div class="example"><pre>
{"B",
 [{"A",
   [],
   [{load_object_code,{ch_app,"1",[ch_sup,ch3]}},
    {load_object_code,{prim_app,"2",[prim_sup]}},
    point_of_no_return,
    {load,{ch_sup,brutal_purge,brutal_purge}},
    {load,{ch3,brutal_purge,brutal_purge}},
    {apply,{application,load,[ch_app]}},
    {suspend,[prim_sup]},
    {load,{prim_sup,brutal_purge,brutal_purge}},
    {code_change,up,[{prim_sup,[]}]},
    {resume,[prim_sup]},
    {apply,{supervisor,restart_child,[prim_sup,ch_sup]}}]}],
 [{"A",
   [],
   [{load_object_code,{prim_app,"1",[prim_sup]}},
    point_of_no_return,
    {apply,{supervisor,terminate_child,[prim_sup,ch_sup]}},
    {apply,{supervisor,delete_child,[prim_sup,ch_sup]}},
    {suspend,[prim_sup]},
    {load,{prim_sup,brutal_purge,brutal_purge}},
    {code_change,down,[{prim_sup,[]}]},
    {resume,[prim_sup]},
    {remove,{ch_sup,brutal_purge,brutal_purge}},
    {remove,{ch3,brutal_purge,brutal_purge}},
    {purge,[ch_sup,ch3]},
    {apply,{application,unload,[ch_app]}}]}]
}.</pre></div>
    
  

  <h3><a name="id79414">12.15 
        Changing Non-Erlang Code</a></h3>
    
    <p>Changing code for a program written in another programming
      language than Erlang, for example a port program, is very
      application dependent and OTP provides no special support for it.</p>
    <p>Example, changing code for a port program: Assume that
      the Erlang process controlling the port is a gen_server
      <span class="code">portc</span> and that the port is opened in the callback function
      <span class="code">init/1</span>:</p>
    <div class="example"><pre>
init(...) -&gt;
    ...,
    PortPrg = filename:join(code:priv_dir(App), "portc"),
    Port = open_port({spawn,PortPrg}, [...]),
    ...,
    {ok, #state{port=Port, ...}}.</pre></div>
    <p>If the port program should be updated, we can extend the code for
      the gen_server with a <span class="code">code_change</span> function which closes
      the old port and opens a new port. (If necessary, the gen_server
      may first request data that needs to be saved from the port
      program and pass this data to the new port):</p>
    <div class="example"><pre>
code_change(_OldVsn, State, port) -&gt;
    State#state.port ! close,
    receive
        {Port,close} -&gt;
            true
    end,
    PortPrg = filename:join(code:priv_dir(App), "portc"),
    Port = open_port({spawn,PortPrg}, [...]),
    {ok, #state{port=Port, ...}}.</pre></div>
    <p>Update the application version number in the <span class="code">.app</span> file
      and write an <span class="code">.appup</span> file:</p>
    <div class="example"><pre>
["2",
 [{"1", [{update, portc, {advanced,port}}]}],
 [{"1", [{update, portc, {advanced,port}}]}]
].</pre></div>
    <p>Make sure the <span class="code">priv</span> directory where the C program is
      located is included in the new release package:</p>
    <div class="example"><pre>
1&gt; <span class="bold_code">systools:make_tar("my_release", [{dirs,[priv]}]).</span>
...</pre></div>
  

  <h3><a name="id79499">12.16 
        Emulator Restart and Upgrade</a></h3>
    
    <p>There are two upgrade instructions that will restart the emulator:</p>
    <dl>
      <dt><strong><span class="code">restart_new_emulator</span></strong></dt>
      <dd>Intended for when erts, kernel, stdlib or sasl is
        upgraded. It is automatically added when the relup file is
        generated by <span class="code">systools:make_relup/3,4</span>. It is executed
        before all other upgrade instructions. See
        <span class="bold_code"><a href="release_handling.html#restart_new_emulator_instr">Release
        Handling</a></span> for more information about this
        instruction.</dd>
      <dt><strong><span class="code">restart_emulator</span></strong></dt>
      <dd>Used when a restart of the emulator is required after all
        other upgrade instructions are executed. See
        <span class="bold_code"><a href="release_handling.html#restart_emulator_instr">Release
        Handling</a></span> for more information about this
        instruction.</dd>
    </dl>

    <p>If an emulator restart is necessary and no upgrade instructions
      are needed, i.e. if the restart itself is enough for the
      upgraded applications to start running the new versions, a very
      simple <span class="code">.relup</span> file can be created manually:</p>
    <div class="example"><pre>
{"B",
 [{"A",
   [],
   [restart_emulator]}],
 [{"A",
   [],
   [restart_emulator]}]
}.</pre></div>
    <p>In this case, the release handler framework with automatic
      packing and unpacking of release packages, automatic path
      updates etc. can be used without having to specify <span class="code">.appup</span>
      files.</p>
  

  <h3><a name="id79575">12.17 
        Emulator Upgrade from pre OTP R15</a></h3>
    
    <p>From OTP R15, an emulator upgrade is performed by restarting
    the emulator with new versions of the core applications
    (<span class="code">kernel</span>, <span class="code">stdlib</span> and <span class="code">sasl</span>) before loading code
    and running upgrade instruction for other applications. For this
    to work, the release to upgrade from must includes OTP R15 or
    later. For the case where the release to upgrade from includes an
    earlier emulator version, <span class="code">systools:make_relup</span> will create a
    backwards compatible relup file. This means that all upgrade
    instructions will be executed before the emulator is
    restarted. The new application code will therefore be loaded into
    the old emulator. If the new code is compiled with the new
    emulator, there might be cases where the beam format has changed
    and beam files can not be loaded. To overcome this problem, the
    new code should be compiled with the old emulator.</p>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>