~ubuntu-branches/ubuntu/trusty/erlang/trusty

« back to all changes in this revision

Viewing changes to system/doc/design_principles/events.xml

  • Committer: Bazaar Package Importer
  • Author(s): Clint Byrum
  • Date: 2011-05-05 15:48:43 UTC
  • mfrom: (3.5.13 sid)
  • Revision ID: james.westby@ubuntu.com-20110505154843-0om6ekzg6m7ugj27
Tags: 1:14.b.2-dfsg-3ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to.
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
  - debian/patches/series: Do what I meant, and enable build-options.patch
    instead.
* Additional changes:
  - Drop erlang-wx from -et
* Dropped Changes:
  - patches/pcre-crash.patch: CVE-2008-2371: outer level option with
    alternatives caused crash. (Applied Upstream)
  - fix for ssl certificate verification in newSSL: 
    ssl_cacertfile_fix.patch (Applied Upstream)
  - debian/patches/series: Enable native.patch again, to get stripped beam
    files and reduce the package size again. (build-options is what
    actually accomplished this)
  - Remove build-options.patch on advice from upstream and because it caused
    odd build failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?xml version="1.0" encoding="latin1" ?>
 
2
<!DOCTYPE chapter SYSTEM "chapter.dtd">
 
3
 
 
4
<chapter>
 
5
  <header>
 
6
    <copyright>
 
7
      <year>1997</year><year>2011</year>
 
8
      <holder>Ericsson AB. All Rights Reserved.</holder>
 
9
    </copyright>
 
10
    <legalnotice>
 
11
      The contents of this file are subject to the Erlang Public License,
 
12
      Version 1.1, (the "License"); you may not use this file except in
 
13
      compliance with the License. You should have received a copy of the
 
14
      Erlang Public License along with this software. If not, it can be
 
15
      retrieved online at http://www.erlang.org/.
 
16
    
 
17
      Software distributed under the License is distributed on an "AS IS"
 
18
      basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
19
      the License for the specific language governing rights and limitations
 
20
      under the License.
 
21
    
 
22
    </legalnotice>
 
23
 
 
24
    <title>Gen_Event Behaviour</title>
 
25
    <prepared></prepared>
 
26
    <docno></docno>
 
27
    <date></date>
 
28
    <rev></rev>
 
29
    <file>events.xml</file>
 
30
  </header>
 
31
  <marker id="gen_event"></marker>
 
32
  <p>This chapter should be read in conjunction with
 
33
    <c>gen_event(3)</c>, where all interface functions and callback
 
34
    functions are described in detail.</p>
 
35
 
 
36
  <section>
 
37
    <title>Event Handling Principles</title>
 
38
    <p>In OTP, an <em>event manager</em> is a named object to which
 
39
      events can be sent. An <em>event</em> could be, for example,
 
40
      an error, an alarm or some information that should be logged.</p>
 
41
    <p>In the event manager, zero, one or several <em>event handlers</em> are installed. When the event manager is notified
 
42
      about an event, the event will be processed by all the installed
 
43
      event handlers. For example, an event manager for handling errors
 
44
      can by default have a handler installed which writes error
 
45
      messages to the terminal. If the error messages during a certain
 
46
      period should be saved to a file as well, the user adds another
 
47
      event handler which does this. When logging to file is no longer
 
48
      necessary, this event handler is deleted.</p>
 
49
    <p>An event manager is implemented as a process and each event
 
50
      handler is implemented as a callback module.</p>
 
51
    <p>The event manager essentially maintains a list of
 
52
      <c>{Module, State}</c> pairs, where each <c>Module</c> is an
 
53
      event handler, and <c>State</c> the internal state of that event
 
54
      handler.</p>
 
55
  </section>
 
56
 
 
57
  <section>
 
58
    <title>Example</title>
 
59
    <p>The callback module for the event handler writing error messages
 
60
      to the terminal could look like:</p>
 
61
    <code type="none">
 
62
-module(terminal_logger).
 
63
-behaviour(gen_event).
 
64
 
 
65
-export([init/1, handle_event/2, terminate/2]).
 
66
 
 
67
init(_Args) ->
 
68
    {ok, []}.
 
69
 
 
70
handle_event(ErrorMsg, State) ->
 
71
    io:format("***Error*** ~p~n", [ErrorMsg]),
 
72
    {ok, State}.
 
73
 
 
74
terminate(_Args, _State) ->
 
75
    ok.</code>
 
76
    <p>The callback module for the event handler writing error messages
 
77
      to a file could look like:</p>
 
78
    <code type="none">
 
79
-module(file_logger).
 
80
-behaviour(gen_event).
 
81
 
 
82
-export([init/1, handle_event/2, terminate/2]).
 
83
 
 
84
init(File) ->
 
85
    {ok, Fd} = file:open(File, read),
 
86
    {ok, Fd}.
 
87
 
 
88
handle_event(ErrorMsg, Fd) ->
 
89
    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
 
90
    {ok, Fd}.
 
91
 
 
92
terminate(_Args, Fd) ->
 
93
    file:close(Fd).</code>
 
94
    <p>The code is explained in the next sections.</p>
 
95
  </section>
 
96
 
 
97
  <section>
 
98
    <marker id="mgr"></marker>
 
99
    <title>Starting an Event Manager</title>
 
100
    <p>To start an event manager for handling errors, as described in
 
101
      the example above, call the following function:</p>
 
102
    <code type="none">
 
103
gen_event:start_link({local, error_man})</code>
 
104
    <p>This function spawns and links to a new process, an event
 
105
      manager.</p>
 
106
    <p>The argument, <c>{local, error_man}</c> specifies the name. In
 
107
      this case, the event manager will be locally registered as
 
108
      <c>error_man</c>.</p>
 
109
    <p>If the name is omitted, the event manager is not registered.
 
110
      Instead its pid must be used. The name could also be given
 
111
      as <c>{global, Name}</c>, in which case the event manager is
 
112
      registered using <c>global:register_name/2</c>.</p>
 
113
    <p><c>gen_event:start_link</c> must be used if the event manager is
 
114
      part of a supervision tree, i.e. is started by a supervisor.
 
115
      There is another function <c>gen_event:start</c> to start a
 
116
      stand-alone event manager, i.e. an event manager which is not
 
117
      part of a supervision tree.</p>
 
118
  </section>
 
119
 
 
120
  <section>
 
121
    <title>Adding an Event Handler</title>
 
122
    <p>Here is an example using the shell on how to start an event
 
123
      manager and add an event handler to it:</p>
 
124
    <pre>
 
125
1> <input>gen_event:start({local, error_man}).</input>
 
126
{ok,&lt;0.31.0>}
 
127
2> <input>gen_event:add_handler(error_man, terminal_logger, []).</input>
 
128
ok</pre>
 
129
    <p>This function sends a message to the event manager registered as
 
130
      <c>error_man</c>, telling it to add the event handler
 
131
      <c>terminal_logger</c>. The event manager will call the callback
 
132
      function <c>terminal_logger:init([])</c>, where the argument []
 
133
      is the third argument to <c>add_handler</c>. <c>init</c> is
 
134
      expected to return <c>{ok, State}</c>, where <c>State</c> is
 
135
      the internal state of the event handler.</p>
 
136
    <code type="none">
 
137
init(_Args) ->
 
138
    {ok, []}.</code>
 
139
    <p>Here, <c>init</c> does not need any input data and ignores its
 
140
      argument. Also, for <c>terminal_logger</c> the internal state is
 
141
      not used. For <c>file_logger</c>, the internal state is used
 
142
      to save the open file descriptor.</p>
 
143
    <code type="none">
 
144
init(File) ->
 
145
    {ok, Fd} = file:open(File, read),
 
146
    {ok, Fd}.</code>
 
147
  </section>
 
148
 
 
149
  <section>
 
150
    <title>Notifying About Events</title>
 
151
    <pre>
 
152
3> <input>gen_event:notify(error_man, no_reply).</input>
 
153
***Error*** no_reply
 
154
ok</pre>
 
155
    <p><c>error_man</c> is the name of the event manager and
 
156
      <c>no_reply</c> is the event.</p>
 
157
    <p>The event is made into a message and sent to the event manager.
 
158
      When the event is received, the event manager calls
 
159
      <c>handle_event(Event, State)</c> for each installed event
 
160
      handler, in the same order as they were added. The function is
 
161
      expected to return a tuple <c>{ok, State1}</c>, where
 
162
      <c>State1</c> is a new value for the state of the event handler.</p>
 
163
    <p>In <c>terminal_logger</c>:</p>
 
164
    <code type="none">
 
165
handle_event(ErrorMsg, State) ->
 
166
    io:format("***Error*** ~p~n", [ErrorMsg]),
 
167
    {ok, State}.</code>
 
168
    <p>In <c>file_logger</c>:</p>
 
169
    <code type="none">
 
170
handle_event(ErrorMsg, Fd) ->
 
171
    io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),
 
172
    {ok, Fd}.</code>
 
173
  </section>
 
174
 
 
175
  <section>
 
176
    <title>Deleting an Event Handler</title>
 
177
    <pre>
 
178
4> <input>gen_event:delete_handler(error_man, terminal_logger, []).</input>
 
179
ok</pre>
 
180
    <p>This function sends a message to the event manager registered as
 
181
      <c>error_man</c>, telling it to delete the event handler
 
182
      <c>terminal_logger</c>. The event manager will call the callback
 
183
      function <c>terminal_logger:terminate([], State)</c>, where
 
184
      the argument [] is the third argument to <c>delete_handler</c>.
 
185
      <c>terminate</c> should be the opposite of <c>init</c> and do any
 
186
      necessary cleaning up. Its return value is ignored.</p>
 
187
    <p>For <c>terminal_logger</c>, no cleaning up is necessary:</p>
 
188
    <code type="none">
 
189
terminate(_Args, _State) ->
 
190
    ok.</code>
 
191
    <p>For <c>file_logger</c>, the file descriptor opened in <c>init</c>
 
192
      needs to be closed:</p>
 
193
    <code type="none">
 
194
terminate(_Args, Fd) ->
 
195
    file:close(Fd).</code>
 
196
  </section>
 
197
 
 
198
  <section>
 
199
    <title>Stopping</title>
 
200
    <p>When an event manager is stopped, it will give each of
 
201
      the installed event handlers the chance to clean up by calling
 
202
      <c>terminate/2</c>, the same way as when deleting a handler.</p>
 
203
 
 
204
    <section>
 
205
      <title>In a Supervision Tree</title>
 
206
      <p>If the event manager is part of a supervision tree, no stop
 
207
        function is needed. The event manager will automatically be
 
208
        terminated by its supervisor. Exactly how this is done is
 
209
        defined by a <seealso marker="sup_princ#shutdown">shutdown strategy</seealso> set in the supervisor.</p>
 
210
    </section>
 
211
 
 
212
    <section>
 
213
      <title>Stand-Alone Event Managers</title>
 
214
      <p>An event manager can also be stopped by calling:</p>
 
215
      <pre>
 
216
> <input>gen_event:stop(error_man).</input>
 
217
ok</pre>
 
218
    </section>
 
219
  </section>
 
220
  <section>
 
221
    <title>Handling Other Messages</title>
 
222
    <p>If the gen_event should be able to receive other messages than
 
223
      events, the callback function <c>handle_info(Info, StateName, StateData)</c>
 
224
      must be implemented to handle them. Examples of
 
225
      other messages are exit messages, if the gen_event is linked to
 
226
      other processes (than the supervisor) and trapping exit signals.</p>
 
227
    <code type="none">
 
228
handle_info({'EXIT', Pid, Reason}, State) ->
 
229
    ..code to handle exits here..
 
230
    {ok, NewState}.</code>
 
231
    <p>The code_change method also has to be implemented.</p>
 
232
    <code type="none">
 
233
code_change(OldVsn, State, Extra) ->
 
234
    ..code to convert state (and more) during code change
 
235
    {ok, NewState}</code>
 
236
  </section>
 
237
</chapter>
 
238