Sophie

Sophie

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

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 -- Gen_Event Behaviour</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="loadscrollpos" title="Gen_Event Behaviour" expanded="true">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>4 Gen_Event Behaviour</h1>
  
  <a name="gen_event"></a>
  <p>This chapter should be read in conjunction with
    <span class="code">gen_event(3)</span>, where all interface functions and callback
    functions are described in detail.</p>

  <h3><a name="id69613">4.1 
        Event Handling Principles</a></h3>
    
    <p>In OTP, an <strong>event manager</strong> is a named object to which
      events can be sent. An <strong>event</strong> could be, for example,
      an error, an alarm or some information that should be logged.</p>
    <p>In the event manager, zero, one or several <strong>event handlers</strong> are installed. When the event manager is notified
      about an event, the event will be processed by all the installed
      event handlers. For example, an event manager for handling errors
      can by default have a handler installed which writes error
      messages to the terminal. If the error messages during a certain
      period should be saved to a file as well, the user adds another
      event handler which does this. When logging to file is no longer
      necessary, this event handler is deleted.</p>
    <p>An event manager is implemented as a process and each event
      handler is implemented as a callback module.</p>
    <p>The event manager essentially maintains a list of
      <span class="code">{Module, State}</span> pairs, where each <span class="code">Module</span> is an
      event handler, and <span class="code">State</span> the internal state of that event
      handler.</p>
  

  <h3><a name="id69665">4.2 
        Example</a></h3>
    
    <p>The callback module for the event handler writing error messages
      to the terminal could look like:</p>
    <div class="example"><pre>
-module(terminal_logger).
-behaviour(gen_event).

-export([init/1, handle_event/2, terminate/2]).

init(_Args) -&gt;
    {ok, []}.

handle_event(ErrorMsg, State) -&gt;
    io:format("***Error*** ~p~n", [ErrorMsg]),
    {ok, State}.

terminate(_Args, _State) -&gt;
    ok.</pre></div>
    <p>The callback module for the event handler writing error messages
      to a file could look like:</p>
    <div class="example"><pre>
-module(file_logger).
-behaviour(gen_event).

-export([init/1, handle_event/2, terminate/2]).

init(File) -&gt;
    {ok, Fd} = file:open(File, read),
    {ok, Fd}.

handle_event(ErrorMsg, Fd) -&gt;
    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
    {ok, Fd}.

terminate(_Args, Fd) -&gt;
    file:close(Fd).</pre></div>
    <p>The code is explained in the next sections.</p>
  

  <h3><a name="id69706">4.3 
        Starting an Event Manager</a></h3>
    <a name="mgr"></a>
    
    <p>To start an event manager for handling errors, as described in
      the example above, call the following function:</p>
    <div class="example"><pre>
gen_event:start_link({local, error_man})</pre></div>
    <p>This function spawns and links to a new process, an event
      manager.</p>
    <p>The argument, <span class="code">{local, error_man}</span> specifies the name. In
      this case, the event manager will be locally registered as
      <span class="code">error_man</span>.</p>
    <p>If the name is omitted, the event manager is not registered.
      Instead its pid must be used. The name could also be given
      as <span class="code">{global, Name}</span>, in which case the event manager is
      registered using <span class="code">global:register_name/2</span>.</p>
    <p><span class="code">gen_event:start_link</span> must be used if the event manager is
      part of a supervision tree, i.e. is started by a supervisor.
      There is another function <span class="code">gen_event:start</span> to start a
      stand-alone event manager, i.e. an event manager which is not
      part of a supervision tree.</p>
  

  <h3><a name="id70832">4.4 
        Adding an Event Handler</a></h3>
    
    <p>Here is an example using the shell on how to start an event
      manager and add an event handler to it:</p>
    <div class="example"><pre>
1&gt; <span class="bold_code">gen_event:start({local, error_man}).</span>
{ok,&lt;0.31.0&gt;}
2&gt; <span class="bold_code">gen_event:add_handler(error_man, terminal_logger, []).</span>
ok</pre></div>
    <p>This function sends a message to the event manager registered as
      <span class="code">error_man</span>, telling it to add the event handler
      <span class="code">terminal_logger</span>. The event manager will call the callback
      function <span class="code">terminal_logger:init([])</span>, where the argument []
      is the third argument to <span class="code">add_handler</span>. <span class="code">init</span> is
      expected to return <span class="code">{ok, State}</span>, where <span class="code">State</span> is
      the internal state of the event handler.</p>
    <div class="example"><pre>
init(_Args) -&gt;
    {ok, []}.</pre></div>
    <p>Here, <span class="code">init</span> does not need any input data and ignores its
      argument. Also, for <span class="code">terminal_logger</span> the internal state is
      not used. For <span class="code">file_logger</span>, the internal state is used
      to save the open file descriptor.</p>
    <div class="example"><pre>
init(File) -&gt;
    {ok, Fd} = file:open(File, read),
    {ok, Fd}.</pre></div>
  

  <h3><a name="id70916">4.5 
        Notifying About Events</a></h3>
    
    <div class="example"><pre>
3&gt; <span class="bold_code">gen_event:notify(error_man, no_reply).</span>
***Error*** no_reply
ok</pre></div>
    <p><span class="code">error_man</span> is the name of the event manager and
      <span class="code">no_reply</span> is the event.</p>
    <p>The event is made into a message and sent to the event manager.
      When the event is received, the event manager calls
      <span class="code">handle_event(Event, State)</span> for each installed event
      handler, in the same order as they were added. The function is
      expected to return a tuple <span class="code">{ok, State1}</span>, where
      <span class="code">State1</span> is a new value for the state of the event handler.</p>
    <p>In <span class="code">terminal_logger</span>:</p>
    <div class="example"><pre>
handle_event(ErrorMsg, State) -&gt;
    io:format("***Error*** ~p~n", [ErrorMsg]),
    {ok, State}.</pre></div>
    <p>In <span class="code">file_logger</span>:</p>
    <div class="example"><pre>
handle_event(ErrorMsg, Fd) -&gt;
    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
    {ok, Fd}.</pre></div>
  

  <h3><a name="id70987">4.6 
        Deleting an Event Handler</a></h3>
    
    <div class="example"><pre>
4&gt; <span class="bold_code">gen_event:delete_handler(error_man, terminal_logger, []).</span>
ok</pre></div>
    <p>This function sends a message to the event manager registered as
      <span class="code">error_man</span>, telling it to delete the event handler
      <span class="code">terminal_logger</span>. The event manager will call the callback
      function <span class="code">terminal_logger:terminate([], State)</span>, where
      the argument [] is the third argument to <span class="code">delete_handler</span>.
      <span class="code">terminate</span> should be the opposite of <span class="code">init</span> and do any
      necessary cleaning up. Its return value is ignored.</p>
    <p>For <span class="code">terminal_logger</span>, no cleaning up is necessary:</p>
    <div class="example"><pre>
terminate(_Args, _State) -&gt;
    ok.</pre></div>
    <p>For <span class="code">file_logger</span>, the file descriptor opened in <span class="code">init</span>
      needs to be closed:</p>
    <div class="example"><pre>
terminate(_Args, Fd) -&gt;
    file:close(Fd).</pre></div>
  

  <h3><a name="id71062">4.7 
        Stopping</a></h3>
    
    <p>When an event manager is stopped, it will give each of
      the installed event handlers the chance to clean up by calling
      <span class="code">terminate/2</span>, the same way as when deleting a handler.</p>

    <h4>In a Supervision Tree</h4>
      
      <p>If the event manager is part of a supervision tree, no stop
        function is needed. The event manager will automatically be
        terminated by its supervisor. Exactly how this is done is
        defined by a <span class="bold_code"><a href="sup_princ.html#shutdown">shutdown strategy</a></span> set in the supervisor.</p>
    

    <h4>Stand-Alone Event Managers</h4>
      
      <p>An event manager can also be stopped by calling:</p>
      <div class="example"><pre>
&gt; <span class="bold_code">gen_event:stop(error_man).</span>
ok</pre></div>
    
  
  <h3><a name="id71116">4.8 
        Handling Other Messages</a></h3>
    
    <p>If the gen_event should be able to receive other messages than
      events, the callback function <span class="code">handle_info(Info, StateName, StateData)</span>
      must be implemented to handle them. Examples of
      other messages are exit messages, if the gen_event is linked to
      other processes (than the supervisor) and trapping exit signals.</p>
    <div class="example"><pre>
handle_info({'EXIT', Pid, Reason}, State) -&gt;
    ..code to handle exits here..
    {ok, NewState}.</pre></div>
    <p>The code_change method also has to be implemented.</p>
    <div class="example"><pre>
code_change(OldVsn, State, Extra) -&gt;
    ..code to convert state (and more) during code change
    {ok, NewState}</pre></div>
  
</div>
<div class="footer">
<hr>
<p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p>
</div>
</div>
</div></body>
</html>