diff options
Diffstat (limited to 'lib/stdlib/doc/src/gen_event.xml')
-rw-r--r-- | lib/stdlib/doc/src/gen_event.xml | 887 |
1 files changed, 488 insertions, 399 deletions
diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml index b2c482d3ed..c24542002a 100644 --- a/lib/stdlib/doc/src/gen_event.xml +++ b/lib/stdlib/doc/src/gen_event.xml @@ -29,19 +29,23 @@ <rev></rev> </header> <module>gen_event</module> - <modulesummary>Generic Event Handling Behaviour</modulesummary> + <modulesummary>Generic event handling behavior.</modulesummary> <description> - <p>A behaviour module for implementing event handling functionality. - The OTP event handling model consists of a generic event manager - process with an arbitrary number of event handlers which are added and - deleted dynamically.</p> - <p>An event manager implemented using this module will have a standard - set of interface functions and include functionality for tracing and - error reporting. It will also fit into an OTP supervision tree. - Refer to <em>OTP Design Principles</em> for more information.</p> + <p>This behavior module provides event handling functionality. It + consists of a generic event manager process with any number of + event handlers that are added and deleted dynamically.</p> + + <p>An event manager implemented using this module has a standard + set of interface functions and includes functionality for tracing and + error reporting. It also fits into an OTP supervision tree. For more + information, see + <seealso marker="doc/design_principles:events">OTP Design Principles</seealso>. + </p> + <p>Each event handler is implemented as a callback module exporting - a pre-defined set of functions. The relationship between the behaviour - functions and the callback functions can be illustrated as follows:</p> + a predefined set of functions. The relationship between the behavior + functions and the callback functions is as follows:</p> + <pre> gen_event module Callback module ---------------- --------------- @@ -69,39 +73,46 @@ gen_event:which_handlers -----> - gen_event:stop -----> Module:terminate/2 - -----> Module:code_change/3</pre> - <p>Since each event handler is one callback module, an event manager - will have several callback modules which are added and deleted - dynamically. Therefore <c>gen_event</c> is more tolerant of callback - module errors than the other behaviours. If a callback function for + + <p>As each event handler is one callback module, an event manager + has many callback modules that are added and deleted + dynamically. <c>gen_event</c> is therefore more tolerant of callback + module errors than the other behaviors. If a callback function for an installed event handler fails with <c>Reason</c>, or returns a - bad value <c>Term</c>, the event manager will not fail. It will delete - the event handler by calling the callback function - <c>Module:terminate/2</c> (see below), giving as argument + bad value <c>Term</c>, the event manager does not fail. It deletes + the event handler by calling callback function + <seealso marker="#Module:terminate/2"><c>Module:terminate/2</c></seealso>, + giving as argument <c>{error,{'EXIT',Reason}}</c> or <c>{error,Term}</c>, respectively. - No other event handler will be affected.</p> - <p>A gen_event process handles system messages as documented in - <seealso marker="sys">sys(3)</seealso>. The <c>sys</c> module + No other event handler is affected.</p> + + <p>A <c>gen_event</c> process handles system messages as described in + <seealso marker="sys"><c>sys(3)</c></seealso>. The <c>sys</c> module can be used for debugging an event manager.</p> - <p>Note that an event manager <em>does</em> trap exit signals + + <p>Notice that an event manager <em>does</em> trap exit signals automatically.</p> - <p>The gen_event process can go into hibernation - (see <seealso marker="erts:erlang#erlang:hibernate/3">erlang(3)</seealso>) if a callback - function in a handler module specifies <c>'hibernate'</c> in its return value. - This might be useful if the server is expected to be idle for a long - time. However this feature should be used with care as hibernation - implies at least two garbage collections (when hibernating and - shortly after waking up) and is not something you'd want to do - between each event handled by a busy event manager.</p> - - <p>It's also worth noting that when multiple event handlers are - invoked, it's sufficient that one single event handler returns a - <c>'hibernate'</c> request for the whole event manager to go into - hibernation.</p> + + <p>The <c>gen_event</c> process can go into hibernation + (see <seealso marker="erts:erlang#hibernate/3"> + <c>erlang:hibernate/3</c></seealso>) if a callback function in + a handler module specifies <c>hibernate</c> in its return value. + This can be useful if the server is expected to be idle for a long + time. However, use this feature with care, as hibernation + implies at least two garbage collections (when hibernating and + shortly after waking up) and is not something you want to do + between each event handled by a busy event manager.</p> + + <p>Notice that when multiple event handlers are + invoked, it is sufficient that one single event handler returns a + <c>hibernate</c> request for the whole event manager to go into + hibernation.</p> <p>Unless otherwise stated, all functions in this module fail if the specified event manager does not exist or if bad arguments are - given.</p> + specified.</p> </description> + <datatypes> <datatype> <name name="handler"/> @@ -116,66 +127,9 @@ gen_event:stop -----> Module:terminate/2 <name name="del_handler_ret"/> </datatype> </datatypes> + <funcs> <func> - <name>start_link() -> Result</name> - <name>start_link(EventMgrName) -> Result</name> - <fsummary>Create a generic event manager process in a supervision tree.</fsummary> - <type> - <v>EventMgrName = {local,Name} | {global,GlobalName} - | {via,Module,ViaName}</v> - <v> Name = atom()</v> - <v> GlobalName = ViaName = term()</v> - <v>Result = {ok,Pid} | {error,{already_started,Pid}}</v> - <v> Pid = pid()</v> - </type> - <desc> - <p>Creates an event manager process as part of a supervision - tree. The function should be called, directly or indirectly, - by the supervisor. It will, among other things, ensure that - the event manager is linked to the supervisor.</p> - <p>If <c>EventMgrName={local,Name}</c>, the event manager is - registered locally as <c>Name</c> using <c>register/2</c>. - If <c>EventMgrName={global,GlobalName}</c>, the event manager is - registered globally as <c>GlobalName</c> using - <c>global:register_name/2</c>. If no name is provided, - the event manager is not registered. - If <c>EventMgrName={via,Module,ViaName}</c>, the event manager will - register with the registry represented by <c>Module</c>. - The <c>Module</c> callback should export the functions - <c>register_name/2</c>, <c>unregister_name/1</c>, - <c>whereis_name/1</c> and <c>send/2</c>, which should behave like the - corresponding functions in <c>global</c>. Thus, - <c>{via,global,GlobalName}</c> is a valid reference.</p> - <p>If the event manager is successfully created the function - returns <c>{ok,Pid}</c>, where <c>Pid</c> is the pid of - the event manager. If there already exists a process with - the specified <c>EventMgrName</c> the function returns - <c>{error,{already_started,Pid}}</c>, where <c>Pid</c> is - the pid of that process.</p> - </desc> - </func> - <func> - <name>start() -> Result</name> - <name>start(EventMgrName) -> Result</name> - <fsummary>Create a stand-alone event manager process.</fsummary> - <type> - <v>EventMgrName = {local,Name} | {global,GlobalName} - | {via,Module,ViaName}</v> - <v> Name = atom()</v> - <v> GlobalName = ViaName = term()</v> - <v>Result = {ok,Pid} | {error,{already_started,Pid}}</v> - <v> Pid = pid()</v> - </type> - <desc> - <p>Creates a stand-alone event manager process, i.e. an event - manager which is not part of a supervision tree and thus has - no supervisor.</p> - <p>See <c>start_link/0,1</c> for a description of arguments and - return values.</p> - </desc> - </func> - <func> <name>add_handler(EventMgrRef, Handler, Args) -> Result</name> <fsummary>Add an event handler to a generic event manager.</fsummary> <type> @@ -191,26 +145,27 @@ gen_event:stop -----> Module:terminate/2 <v> Reason = term()</v> </type> <desc> - <p>Adds a new event handler to the event manager <c>EventMgrRef</c>. - The event manager will call <c>Module:init/1</c> to initiate - the event handler and its internal state.</p> - <p><c>EventMgrRef</c> can be:</p> + <p>Adds a new event handler to event manager <c>EventMgrRef</c>. + The event manager calls + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> + to initiate the event handler and its internal state.</p> + <p><c>EventMgrRef</c> can be any of the following:</p> <list type="bulleted"> - <item>the pid,</item> - <item><c>Name</c>, if the event manager is locally registered,</item> + <item>The pid</item> + <item><c>Name</c>, if the event manager is locally registered</item> <item><c>{Name,Node}</c>, if the event manager is locally - registered at another node, or</item> + registered at another node</item> <item><c>{global,GlobalName}</c>, if the event manager is globally - registered.</item> - <item><c>{via,Module,ViaName}</c>, if the event manager is registered - through an alternative process registry.</item> + registered</item> + <item><c>{via,Module,ViaName}</c>, if the event manager is registered + through an alternative process registry</item> </list> <p><c>Handler</c> is the name of the callback module <c>Module</c> or a tuple <c>{Module,Id}</c>, where <c>Id</c> is any term. The <c>{Module,Id}</c> representation makes it possible to - identify a specific event handler when there are several event - handlers using the same callback module.</p> - <p><c>Args</c> is an arbitrary term which is passed as the argument + identify a specific event handler when many event handlers + use the same callback module.</p> + <p><c>Args</c> is any term that is passed as the argument to <c>Module:init/1</c>.</p> <p>If <c>Module:init/1</c> returns a correct value indicating successful completion, the event manager adds the event @@ -221,9 +176,11 @@ gen_event:stop -----> Module:terminate/2 <c>{error,Reason}</c>, respectively.</p> </desc> </func> + <func> <name>add_sup_handler(EventMgrRef, Handler, Args) -> Result</name> - <fsummary>Add a supervised event handler to a generic event manager.</fsummary> + <fsummary>Add a supervised event handler to a generic event manager. + </fsummary> <type> <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()</v> @@ -237,63 +194,52 @@ gen_event:stop -----> Module:terminate/2 <v> Reason = term()</v> </type> <desc> - <p>Adds a new event handler in the same way as <c>add_handler/3</c> - but will also supervise the connection between the event handler + <p>Adds a new event handler in the same way as + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>, + but also supervises the connection between the event handler and the calling process.</p> <list type="bulleted"> <item>If the calling process later terminates with <c>Reason</c>, - the event manager will delete the event handler by calling - <c>Module:terminate/2</c> with <c>{stop,Reason}</c> as argument.</item> + the event manager deletes the event handler by calling + <seealso marker="#Module:terminate/2"> + <c>Module:terminate/2</c></seealso> + with <c>{stop,Reason}</c> as argument. + </item> <item> - <p>If the event handler later is deleted, the event manager + <p>If the event handler is deleted later, the event manager sends a message<c>{gen_event_EXIT,Handler,Reason}</c> to the calling process. <c>Reason</c> is one of the following:</p> <list type="bulleted"> - <item><c>normal</c>, if the event handler has been removed due to a - call to <c>delete_handler/3</c>, or <c>remove_handler</c> - has been returned by a callback function (see below).</item> - <item><c>shutdown</c>, if the event handler has been removed - because the event manager is terminating.</item> - <item><c>{swapped,NewHandler,Pid}</c>, if the process <c>Pid</c> - has replaced the event handler with another event handler - <c>NewHandler</c> using a call to <c>swap_handler/3</c> or - <c>swap_sup_handler/3</c>.</item> - <item>a term, if the event handler is removed due to an error. - Which term depends on the error.</item> + <item> + <p><c>normal</c>, if the event handler has been removed + because of a + call to <c>delete_handler/3</c>, or <c>remove_handler</c> + has been returned by a callback function (see below).</p> + </item> + <item> + <p><c>shutdown</c>, if the event handler has been removed + because the event manager is terminating.</p> + </item> + <item> + <p><c>{swapped,NewHandler,Pid}</c>, if the process <c>Pid</c> + has replaced the event handler with another event handler + <c>NewHandler</c> using a call to + <seealso marker="#swap_handler/3"> + <c>swap_handler/3</c></seealso> or + <seealso marker="#swap_sup_handler/3"> + <c>swap_sup_handler/3</c></seealso>.</p> + </item> + <item> + <p>A term, if the event handler is removed because of an error. + Which term depends on the error.</p></item> </list> </item> </list> - <p>See <c>add_handler/3</c> for a description of the arguments - and return values.</p> - </desc> - </func> - <func> - <name>notify(EventMgrRef, Event) -> ok</name> - <name>sync_notify(EventMgrRef, Event) -> ok</name> - <fsummary>Notify an event manager about an event.</fsummary> - <type> - <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName} - | {via,Module,ViaName} | pid()</v> - <v> Name = Node = atom()</v> - <v> GlobalName = ViaName = term()</v> - <v>Event = term()</v> - </type> - <desc> - <p>Sends an event notification to the event manager - <c>EventMgrRef</c>. The event manager will call - <c>Module:handle_event/2</c> for each installed event handler to - handle the event.</p> - <p><c>notify</c> is asynchronous and will return immediately after - the event notification has been sent. <c>sync_notify</c> is - synchronous in the sense that it will return <c>ok</c> after - the event has been handled by all event handlers.</p> - <p>See <c>add_handler/3</c> for a description of <c>EventMgrRef</c>.</p> - <p><c>Event</c> is an arbitrary term which is passed as one of - the arguments to <c>Module:handle_event/2</c>.</p> - <p><c>notify</c> will not fail even if the specified event manager - does not exist, unless it is specified as <c>Name</c>.</p> + <p>For a description of the arguments and return values, see + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>.</p> </desc> </func> + <func> <name>call(EventMgrRef, Handler, Request) -> Result</name> <name>call(EventMgrRef, Handler, Request, Timeout) -> Result</name> @@ -314,18 +260,18 @@ gen_event:stop -----> Module:terminate/2 <v> Reason = term()</v> </type> <desc> - <p>Makes a synchronous call to the event handler <c>Handler</c> - installed in the event manager <c>EventMgrRef</c> by sending a - request and waiting until a reply arrives or a timeout occurs. - The event manager will call <c>Module:handle_call/2</c> to handle - the request.</p> - <p>See <c>add_handler/3</c> for a description of <c>EventMgrRef</c> - and <c>Handler</c>.</p> - <p><c>Request</c> is an arbitrary term which is passed as one of + <p>Makes a synchronous call to event handler <c>Handler</c> + installed in event manager <c>EventMgrRef</c> by sending a + request and waiting until a reply arrives or a time-out occurs. + The event manager calls <seealso marker="#Module:handle_call/2"> + <c>Module:handle_call/2</c></seealso> to handle the request.</p> + <p>For a description of <c>EventMgrRef</c> and <c>Handler</c>, see + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>.</p> + <p><c>Request</c> is any term that is passed as one of the arguments to <c>Module:handle_call/2</c>.</p> - <p><c>Timeout</c> is an integer greater than zero which specifies + <p><c>Timeout</c> is an integer greater than zero that specifies how many milliseconds to wait for a reply, or the atom - <c>infinity</c> to wait indefinitely. Default value is 5000. + <c>infinity</c> to wait indefinitely. Defaults to 5000. If no reply is received within the specified time, the function call fails.</p> <p>The return value <c>Reply</c> is defined in the return value of @@ -337,7 +283,8 @@ gen_event:stop -----> Module:terminate/2 respectively.</p> </desc> </func> - <func> + + <func> <name>delete_handler(EventMgrRef, Handler, Args) -> Result</name> <fsummary>Delete an event handler from a generic event manager.</fsummary> <type> @@ -353,12 +300,14 @@ gen_event:stop -----> Module:terminate/2 <v> Reason = term()</v> </type> <desc> - <p>Deletes an event handler from the event manager - <c>EventMgrRef</c>. The event manager will call - <c>Module:terminate/2</c> to terminate the event handler.</p> - <p>See <c>add_handler/3</c> for a description of <c>EventMgrRef</c> - and <c>Handler</c>.</p> - <p><c>Args</c> is an arbitrary term which is passed as one of + <p>Deletes an event handler from event manager + <c>EventMgrRef</c>. The event manager calls + <seealso marker="#Module:terminate/2"> + <c>Module:terminate/2</c></seealso> to terminate the event + handler.</p> + <p>For a description of <c>EventMgrRef</c> and <c>Handler</c>, see + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>.</p> + <p><c>Args</c> is any term that is passed as one of the arguments to <c>Module:terminate/2</c>.</p> <p>The return value is the return value of <c>Module:terminate/2</c>. If the specified event handler is not installed, the function @@ -367,6 +316,148 @@ gen_event:stop -----> Module:terminate/2 <c>{'EXIT',Reason}</c>.</p> </desc> </func> + + <func> + <name>notify(EventMgrRef, Event) -> ok</name> + <name>sync_notify(EventMgrRef, Event) -> ok</name> + <fsummary>Notify an event manager about an event.</fsummary> + <type> + <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName} + | {via,Module,ViaName} | pid()</v> + <v> Name = Node = atom()</v> + <v> GlobalName = ViaName = term()</v> + <v>Event = term()</v> + </type> + <desc> + <p>Sends an event notification to event manager + <c>EventMgrRef</c>. The event manager calls + <seealso marker="#Module:handle_event/2"> + <c>Module:handle_event/2</c></seealso> + for each installed event handler to handle the event.</p> + <p><c>notify/2</c> is asynchronous and returns immediately after + the event notification has been sent. <c>sync_notify/2</c> is + synchronous in the sense that it returns <c>ok</c> after + the event has been handled by all event handlers.</p> + <p>For a description of <c>EventMgrRef</c>, see + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>.</p> + <p><c>Event</c> is any term that is passed as one of + the arguments to <seealso marker="#Module:handle_event/2"> + <c>Module:handle_event/2</c></seealso>.</p> + <p><c>notify/1</c> does not fail even if the specified event manager + does not exist, unless it is specified as <c>Name</c>.</p> + </desc> + </func> + + <func> + <name>start() -> Result</name> + <name>start(EventMgrName) -> Result</name> + <fsummary>Create a stand-alone event manager process.</fsummary> + <type> + <v>EventMgrName = {local,Name} | {global,GlobalName} + | {via,Module,ViaName}</v> + <v> Name = atom()</v> + <v> GlobalName = ViaName = term()</v> + <v>Result = {ok,Pid} | {error,{already_started,Pid}}</v> + <v> Pid = pid()</v> + </type> + <desc> + <p>Creates a stand-alone event manager process, that is, an event + manager that is not part of a supervision tree and thus has + no supervisor.</p> + <p>For a description of the arguments and return values, see + <seealso marker="#start_link/0"><c>start_link/0,1</c></seealso>.</p> + </desc> + </func> + + <func> + <name>start_link() -> Result</name> + <name>start_link(EventMgrName) -> Result</name> + <fsummary>Create a generic event manager process in a supervision tree. + </fsummary> + <type> + <v>EventMgrName = {local,Name} | {global,GlobalName} + | {via,Module,ViaName}</v> + <v> Name = atom()</v> + <v> GlobalName = ViaName = term()</v> + <v>Result = {ok,Pid} | {error,{already_started,Pid}}</v> + <v> Pid = pid()</v> + </type> + <desc> + <p>Creates an event manager process as part of a supervision + tree. The function is to be called, directly or indirectly, + by the supervisor. For example, it ensures that + the event manager is linked to the supervisor.</p> + <list type="bulleted"> + <item> + <p>If <c>EventMgrName={local,Name}</c>, the event manager is + registered locally as <c>Name</c> using <c>register/2</c>.</p> + </item> + <item> + <p>If <c>EventMgrName={global,GlobalName}</c>, the event manager is + registered globally as <c>GlobalName</c> using + <seealso marker="kernel:global#register_name/2"> + <c>global:register_name/2</c></seealso>. + If no name is provided, the event manager is not registered.</p> + </item> + <item> + <p>If <c>EventMgrName={via,Module,ViaName}</c>, the event manager + registers with the registry represented by <c>Module</c>. + The <c>Module</c> callback is to export the functions + <c>register_name/2</c>, <c>unregister_name/1</c>, + <c>whereis_name/1</c>, and <c>send/2</c>, which are to behave + as the corresponding functions in + <seealso marker="kernel:global"><c>global</c></seealso>. + Thus, <c>{via,global,GlobalName}</c> is a valid reference.</p> + </item> + </list> + <p>If the event manager is successfully created, the function + returns <c>{ok,Pid}</c>, where <c>Pid</c> is the pid of + the event manager. If a process with the specified + <c>EventMgrName</c> exists already, the function returns + <c>{error,{already_started,Pid}}</c>, where <c>Pid</c> is + the pid of that process.</p> + </desc> + </func> + + <func> + <name>stop(EventMgrRef) -> ok</name> + <name>stop(EventMgrRef, Reason, Timeout) -> ok</name> + <fsummary>Terminate a generic event manager.</fsummary> + <type> + <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName} + | {via,Module,ViaName} | pid()</v> + <v>Name = Node = atom()</v> + <v>GlobalName = ViaName = term()</v> + <v>Reason = term()</v> + <v>Timeout = int()>0 | infinity</v> + </type> + <desc> + <p>Orders event manager <c>EventMgrRef</c> to exit with + the specifies <c>Reason</c> and waits for it to + terminate. Before terminating, <c>gen_event</c> calls + <seealso marker="#Module:terminate/2"> + <c>Module:terminate(stop,...)</c></seealso> + for each installed event handler.</p> + <p>The function returns <c>ok</c> if the event manager terminates + with the expected reason. Any other reason than <c>normal</c>, + <c>shutdown</c>, or <c>{shutdown,Term}</c> causes an + error report to be issued using + <seealso marker="kernel:error_logger#format/2"> + <c>error_logger:format/2</c></seealso>. + The default <c>Reason</c> is <c>normal</c>.</p> + <p><c>Timeout</c> is an integer greater than zero that + specifies how many milliseconds to wait for the event manager to + terminate, or the atom <c>infinity</c> to wait + indefinitely. Defaults to <c>infinity</c>. If the + event manager has not terminated within the specified time, a + <c>timeout</c> exception is raised.</p> + <p>If the process does not exist, a <c>noproc</c> exception + is raised.</p> + <p>For a description of <c>EventMgrRef</c>, see + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>.</p> + </desc> + </func> + <func> <name>swap_handler(EventMgrRef, {Handler1,Args1}, {Handler2,Args2}) -> Result</name> <fsummary>Replace an event handler in a generic event manager.</fsummary> @@ -385,34 +476,35 @@ gen_event:stop -----> Module:terminate/2 </type> <desc> <p>Replaces an old event handler with a new event handler in - the event manager <c>EventMgrRef</c>.</p> - <p>See <c>add_handler/3</c> for a description of the arguments.</p> + event manager <c>EventMgrRef</c>.</p> + <p>For a description of the arguments, see + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>.</p> <p>First the old event handler <c>Handler1</c> is deleted. The event manager calls <c>Module1:terminate(Args1, ...)</c>, where <c>Module1</c> is the callback module of <c>Handler1</c>, and collects the return value.</p> <p>Then the new event handler <c>Handler2</c> is added and initiated by calling <c>Module2:init({Args2,Term})</c>, where <c>Module2</c> - is the callback module of <c>Handler2</c> and <c>Term</c> + is the callback module of <c>Handler2</c> and <c>Term</c> is the return value of <c>Module1:terminate/2</c>. This makes it possible to transfer information from <c>Handler1</c> to <c>Handler2</c>.</p> - <p>The new handler will be added even if the the specified old event - handler is not installed in which case <c>Term=error</c>, or if - <c>Module1:terminate/2</c> fails with <c>Reason</c> in which case - <c>Term={'EXIT',Reason}</c>. - The old handler will be deleted even if <c>Module2:init/1</c> - fails.</p> + <p>The new handler is added even if the the specified old event + handler is not installed, in which case <c>Term=error</c>, or if + <c>Module1:terminate/2</c> fails with <c>Reason</c>, + in which case <c>Term={'EXIT',Reason}</c>. + The old handler is deleted even if <c>Module2:init/1</c> fails.</p> <p>If there was a supervised connection between <c>Handler1</c> and - a process <c>Pid</c>, there will be a supervised connection + a process <c>Pid</c>, there is a supervised connection between <c>Handler2</c> and <c>Pid</c> instead.</p> <p>If <c>Module2:init/1</c> returns a correct value, this function returns <c>ok</c>. If <c>Module2:init/1</c> fails with - <c>Reason</c> or returns an unexpected value <c>Term</c>, this + <c>Reason</c> or returns an unexpected value <c>Term</c>, this function returns <c>{error,{'EXIT',Reason}}</c> or <c>{error,Term}</c>, respectively.</p> </desc> </func> + <func> <name>swap_sup_handler(EventMgrRef, {Handler1,Args1}, {Handler2,Args2}) -> Result</name> <fsummary>Replace an event handler in a generic event manager.</fsummary> @@ -430,16 +522,18 @@ gen_event:stop -----> Module:terminate/2 <v> Reason = term()</v> </type> <desc> - <p>Replaces an event handler in the event manager <c>EventMgrRef</c> - in the same way as <c>swap_handler/3</c> but will also supervise + <p>Replaces an event handler in event manager <c>EventMgrRef</c> + in the same way as <c>swap_handler/3</c>, but also supervises the connection between <c>Handler2</c> and the calling process.</p> - <p>See <c>swap_handler/3</c> for a description of the arguments - and return values.</p> + <p>For a description of the arguments and return values, see + <seealso marker="#swap_handler/3"><c>swap_handler/3</c></seealso>.</p> </desc> </func> + <func> <name>which_handlers(EventMgrRef) -> [Handler]</name> - <fsummary>Return all event handlers installed in a generic event manager.</fsummary> + <fsummary>Return all event handlers installed in a generic event manager. + </fsummary> <type> <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()</v> @@ -450,132 +544,106 @@ gen_event:stop -----> Module:terminate/2 <v> Id = term()</v> </type> <desc> - <p>Returns a list of all event handlers installed in the event + <p>Returns a list of all event handlers installed in event manager <c>EventMgrRef</c>.</p> - <p>See <c>add_handler/3</c> for a description of <c>EventMgrRef</c> - and <c>Handler</c>.</p> - </desc> - </func> - <func> - <name>stop(EventMgrRef) -> ok</name> - <name>stop(EventMgrRef, Reason, Timeout) -> ok</name> - <fsummary>Terminate a generic event manager.</fsummary> - <type> - <v>EventMgrRef = Name | {Name,Node} | {global,GlobalName} - | {via,Module,ViaName} | pid()</v> - <v>Name = Node = atom()</v> - <v>GlobalName = ViaName = term()</v> - <v>Reason = term()</v> - <v>Timeout = int()>0 | infinity</v> - </type> - <desc> - <p>Orders the event manager <c>EventMgrRef</c> to exit with - the given <c>Reason</c> and waits for it to - terminate. Before terminating, the gen_event will call - <seealso marker="#Module:terminate/2">Module:terminate(stop,...)</seealso> - for each installed event handler.</p> - <p>The function returns <c>ok</c> if the event manager terminates - with the expected reason. Any other reason than <c>normal</c>, - <c>shutdown</c>, or <c>{shutdown,Term}</c> will cause an - error report to be issued using - <seealso marker="kernel:error_logger#format/2">error_logger:format/2</seealso>. - The default <c>Reason</c> is <c>normal</c>.</p> - <p><c>Timeout</c> is an integer greater than zero which - specifies how many milliseconds to wait for the event manager to - terminate, or the atom <c>infinity</c> to wait - indefinitely. The default value is <c>infinity</c>. If the - event manager has not terminated within the specified time, a - <c>timeout</c> exception is raised.</p> - <p>If the process does not exist, a <c>noproc</c> exception - is raised.</p> - <p>See <c>add_handler/3</c> for a description of <c>EventMgrRef</c>.</p> + <p>For a description of <c>EventMgrRef</c> and <c>Handler</c>, see + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso>.</p> </desc> </func> </funcs> <section> - <title>CALLBACK FUNCTIONS</title> - <p>The following functions should be exported from a <c>gen_event</c> + <title>Callback Functions</title> + <p>The following functions are to be exported from a <c>gen_event</c> callback module.</p> </section> + <funcs> <func> - <name>Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate} | {error,Reason}</name> - <fsummary>Initialize an event handler.</fsummary> + <name>Module:code_change(OldVsn, State, Extra) -> {ok, NewState}</name> + <fsummary>Update the internal state during upgrade/downgrade.</fsummary> <type> - <v>InitArgs = Args | {Args,Term}</v> - <v> Args = Term = term()</v> - <v>State = term()</v> - <v>Reason = term()</v> + <v>OldVsn = Vsn | {down, Vsn}</v> + <v> Vsn = term()</v> + <v>State = NewState = term()</v> + <v>Extra = term()</v> </type> <desc> - <p>Whenever a new event handler is added to an event manager, - this function is called to initialize the event handler.</p> - <p>If the event handler is added due to a call to - <c>gen_event:add_handler/3</c> or - <c>gen_event:add_sup_handler/3</c>, <c>InitArgs</c> is - the <c>Args</c> argument of these functions.</p> - <p>If the event handler is replacing another event handler due to - a call to <c>gen_event:swap_handler/3</c> or - <c>gen_event:swap_sup_handler/3</c>, or due to a <c>swap</c> - return tuple from one of the other callback functions, - <c>InitArgs</c> is a tuple <c>{Args,Term}</c> where <c>Args</c> is - the argument provided in the function call/return tuple and - <c>Term</c> is the result of terminating the old event handler, - see <c>gen_event:swap_handler/3</c>.</p> - <p>If successful, the function should return <c>{ok,State}</c> - or <c>{ok,State,hibernate}</c> where <c>State</c> is the - initial internal state of the event handler.</p> - <p>If <c>{ok,State,hibernate}</c> is returned, the event - manager will go into hibernation (by calling <seealso - marker="proc_lib#hibernate/3">proc_lib:hibernate/3</seealso>), - waiting for the next event to occur.</p> + <p>This function is called for an installed event handler that + is to update its internal state during a release + upgrade/downgrade, that is, when the instruction + <c>{update,Module,Change,...}</c>, where + <c>Change={advanced,Extra}</c>, is specified in the <c>.appup</c> + file. For more information, see <seealso + marker="doc/design_principles:users_guide">OTP Design Principles</seealso>.</p> + <p>For an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and for a downgrade, + <c>OldVsn</c> is <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the + <c>vsn</c> attribute(s) of the old version of the callback module + <c>Module</c>. If no such attribute is defined, the version + is the checksum of the Beam file.</p> + <p><c>State</c> is the internal state of the event handler.</p> + <p><c>Extra</c> is passed "as is" from the <c>{advanced,Extra}</c> + part of the update instruction.</p> + <p>The function is to return the updated internal state.</p> </desc> </func> + <func> - <name>Module:handle_event(Event, State) -> Result</name> - <fsummary>Handle an event.</fsummary> + <name>Module:format_status(Opt, [PDict, State]) -> Status</name> + <fsummary>Optional function for providing a term describing the + current event handler state.</fsummary> <type> - <v>Event = term()</v> + <v>Opt = normal | terminate</v> + <v>PDict = [{Key, Value}]</v> <v>State = term()</v> - <v>Result = {ok,NewState} | {ok,NewState,hibernate} </v> - <v> | {swap_handler,Args1,NewState,Handler2,Args2} | remove_handler</v> - <v> NewState = term()</v> - <v> Args1 = Args2 = term()</v> - <v> Handler2 = Module2 | {Module2,Id}</v> - <v> Module2 = atom()</v> - <v> Id = term()</v> + <v>Status = term()</v> </type> <desc> - <p>Whenever an event manager receives an event sent using - <c>gen_event:notify/2</c> or <c>gen_event:sync_notify/2</c>, this - function is called for each installed event handler to handle - the event.</p> - <p><c>Event</c> is the <c>Event</c> argument of - <c>notify</c>/<c>sync_notify</c>.</p> + <note> + <p>This callback is optional, so event handler modules need + not export it. If a handler does not export this function, + the <c>gen_event</c> module uses the handler state directly for + the purposes described below.</p> + </note> + <p>This function is called by a <c>gen_event</c> process in the + following situations:</p> + <list type="bulleted"> + <item>One of <seealso marker="sys#get_status/1"> + <c>sys:get_status/1,2</c></seealso> + is invoked to get the <c>gen_event</c> status. <c>Opt</c> is set + to the atom <c>normal</c> for this case.</item> + <item>The event handler terminates abnormally and <c>gen_event</c> + logs an error. <c>Opt</c> is set to the + atom <c>terminate</c> for this case.</item> + </list> + <p>This function is useful for changing the form and + appearance of the event handler state for these cases. An + event handler callback module wishing to change the + the <c>sys:get_status/1,2</c> return value as well as how + its state appears in termination error logs, exports an + instance of <c>format_status/2</c> that returns a term + describing the current state of the event handler.</p> + <p><c>PDict</c> is the current value of the + process dictionary of <c>gen_event</c>.</p> <p><c>State</c> is the internal state of the event handler.</p> - <p>If the function returns <c>{ok,NewState}</c> or <c>{ok,NewState,hibernate}</c> - the event handler - will remain in the event manager with the possible updated - internal state <c>NewState</c>.</p> - <p>If <c>{ok,NewState,hibernate}</c> is returned, the event - manager will also go into hibernation (by calling <seealso - marker="proc_lib#hibernate/3">proc_lib:hibernate/3</seealso>), - waiting for the next event to occur. It is sufficient that one of the event - handlers return <c>{ok,NewState,hibernate}</c> for the whole event manager - process to hibernate.</p> - <p>If the function returns - <c>{swap_handler,Args1,NewState,Handler2,Args2}</c> the event - handler will be replaced by <c>Handler2</c> by first calling - <c>Module:terminate(Args1,NewState)</c> and then - <c>Module2:init({Args2,Term})</c> where <c>Term</c> is the return - value of <c>Module:terminate/2</c>. - See <c>gen_event:swap_handler/3</c> for more information.</p> - <p>If the function returns <c>remove_handler</c> the event handler - will be deleted by calling - <c>Module:terminate(remove_handler,State)</c>.</p> + <p>The function is to return <c>Status</c>, a term that + change the details of the current state of the event + handler. Any term is allowed for <c>Status</c>. The + <c>gen_event</c> module uses <c>Status</c> as follows:</p> + <list type="bulleted"> + <item><p>When <c>sys:get_status/1,2</c> is called, <c>gen_event</c> + ensures that its return value contains <c>Status</c> in + place of the state term of the event handler.</p></item> + <item><p>When an event handler terminates abnormally, <c>gen_event</c> + logs <c>Status</c> in place of the state term of the + event handler.</p></item> + </list> + <p>One use for this function is to return compact alternative + state representations to avoid that large state terms + are printed in log files.</p> </desc> </func> + <func> <name>Module:handle_call(Request, State) -> Result</name> <fsummary>Handle a synchronous request.</fsummary> @@ -594,15 +662,77 @@ gen_event:stop -----> Module:terminate/2 </type> <desc> <p>Whenever an event manager receives a request sent using - <c>gen_event:call/3,4</c>, this function is called for + <seealso marker="#call/3"><c>call/3,4</c></seealso>, + this function is called for the specified event handler to handle the request.</p> - <p><c>Request</c> is the <c>Request</c> argument of <c>call</c>.</p> + <p><c>Request</c> is the <c>Request</c> argument of <c>call/3,4</c>.</p> + <p><c>State</c> is the internal state of the event handler.</p> + <p>The return values are the same as for + <seealso marker="#Module:handle_event/2"> + <c>Module:handle_event/2</c></seealso> + except that they also contain a term <c>Reply</c>, which is the reply + to the client as the return value of <c>call/3,4</c>.</p> + </desc> + </func> + + <func> + <name>Module:handle_event(Event, State) -> Result</name> + <fsummary>Handle an event.</fsummary> + <type> + <v>Event = term()</v> + <v>State = term()</v> + <v>Result = {ok,NewState} | {ok,NewState,hibernate} </v> + <v> | {swap_handler,Args1,NewState,Handler2,Args2} + | remove_handler</v> + <v> NewState = term()</v> + <v> Args1 = Args2 = term()</v> + <v> Handler2 = Module2 | {Module2,Id}</v> + <v> Module2 = atom()</v> + <v> Id = term()</v> + </type> + <desc> + <p>Whenever an event manager receives an event sent using + <seealso marker="#notify/2"><c>notify/2</c></seealso> or + <seealso marker="#sync_notify/2"><c>sync_notify/2</c></seealso>, + this function is called for each installed event handler to handle + the event.</p> + <p><c>Event</c> is the <c>Event</c> argument of + <c>notify/2</c>/<c>sync_notify/2</c>.</p> <p><c>State</c> is the internal state of the event handler.</p> - <p>The return values are the same as for <c>handle_event/2</c> - except they also contain a term <c>Reply</c> which is the reply - given back to the client as the return value of <c>call</c>.</p> + <list type="bulleted"> + <item> + <p>If <c>{ok,NewState}</c> or <c>{ok,NewState,hibernate}</c> + is returned, the event handler + remains in the event manager with the possible updated + internal state <c>NewState</c>.</p> + </item> + <item> + <p>If <c>{ok,NewState,hibernate}</c> is returned, the event + manager also goes into hibernation (by calling + <seealso marker="proc_lib#hibernate/3"> + <c>proc_lib:hibernate/3</c></seealso>), waiting for the next + event to occur. It is sufficient that one of the + event handlers return <c>{ok,NewState,hibernate}</c> for the + whole event manager process to hibernate.</p> + </item> + <item> + <p>If <c>{swap_handler,Args1,NewState,Handler2,Args2}</c> is + returned, the event handler is replaced by <c>Handler2</c> by + first calling <c>Module:terminate(Args1,NewState)</c> and then + <c>Module2:init({Args2,Term})</c>, where <c>Term</c> is the return + value of <c>Module:terminate/2</c>. For more information, see + <seealso marker="#swap_handler/3"><c>swap_handler/3</c></seealso>. + </p> + </item> + <item> + <p>If <c>remove_handler</c> is returned, the event handler is + deleted by calling + <c>Module:terminate(remove_handler,State)</c>.</p> + </item> + </list> </desc> </func> + <func> <name>Module:handle_info(Info, State) -> Result</name> <fsummary>Handle an incoming message.</fsummary> @@ -610,7 +740,8 @@ gen_event:stop -----> Module:terminate/2 <v>Info = term()</v> <v>State = term()</v> <v>Result = {ok,NewState} | {ok,NewState,hibernate}</v> - <v> | {swap_handler,Args1,NewState,Handler2,Args2} | remove_handler</v> + <v> | {swap_handler,Args1,NewState,Handler2,Args2} + | remove_handler</v> <v> NewState = term()</v> <v> Args1 = Args2 = term()</v> <v> Handler2 = Module2 | {Module2,Id}</v> @@ -622,10 +753,49 @@ gen_event:stop -----> Module:terminate/2 an event manager receives any other message than an event or a synchronous request (or a system message).</p> <p><c>Info</c> is the received message.</p> - <p>See <c>Module:handle_event/2</c> for a description of State - and possible return values.</p> + <p>For a description of <c>State</c> and possible return values, see + <seealso marker="#Module:handle_event/2"> + <c>Module:handle_event/2</c></seealso>.</p> + </desc> + </func> + + <func> + <name>Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate} | {error,Reason}</name> + <fsummary>Initialize an event handler.</fsummary> + <type> + <v>InitArgs = Args | {Args,Term}</v> + <v> Args = Term = term()</v> + <v>State = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Whenever a new event handler is added to an event manager, + this function is called to initialize the event handler.</p> + <p>If the event handler is added because of a call to + <seealso marker="#add_handler/3"><c>add_handler/3</c></seealso> or + <seealso marker="#add_sup_handler/3"> + <c>add_sup_handler/3</c></seealso>, <c>InitArgs</c> is + the <c>Args</c> argument of these functions.</p> + <p>If the event handler replaces another event handler because of + a call to + <seealso marker="#swap_handler/3"><c>swap_handler/3</c></seealso> or + <seealso marker="#swap_sup_handler/3"> + <c>swap_sup_handler/3</c></seealso>, or because of a <c>swap</c> + return tuple from one of the other callback functions, + <c>InitArgs</c> is a tuple <c>{Args,Term}</c>, where <c>Args</c> is + the argument provided in the function call/return tuple and + <c>Term</c> is the result of terminating the old event handler, see + <seealso marker="#swap_handler/3"><c>swap_handler/3</c></seealso>.</p> + <p>If successful, the function returns <c>{ok,State}</c> + or <c>{ok,State,hibernate}</c>, where <c>State</c> is the + initial internal state of the event handler.</p> + <p>If <c>{ok,State,hibernate}</c> is returned, the event + manager goes into hibernation (by calling <seealso + marker="proc_lib#hibernate/3"><c>proc_lib:hibernate/3</c></seealso>), + waiting for the next event to occur.</p> </desc> </func> + <func> <name>Module:terminate(Arg, State) -> term()</name> <fsummary>Clean up before deletion.</fsummary> @@ -636,22 +806,25 @@ gen_event:stop -----> Module:terminate/2 </type> <desc> <p>Whenever an event handler is deleted from an event manager, - this function is called. It should be the opposite of - <c>Module:init/1</c> and do any necessary cleaning up.</p> - <p>If the event handler is deleted due to a call to - <c>gen_event:delete_handler</c>, <c>gen_event:swap_handler/3</c> - or <c>gen_event:swap_sup_handler/3</c>, <c>Arg</c> is + this function is called. It is to be the opposite of + <seealso marker="#Module:init/1"><c>Module:init/1</c></seealso> + and do any necessary cleaning up.</p> + <p>If the event handler is deleted because of a call to + <seealso marker="#delete_handler/3"><c>delete_handler/3</c></seealso>, + <seealso marker="#swap_handler/3"><c>swap_handler/3</c></seealso>, or + <seealso marker="#swap_sup_handler/3"> + <c>swap_sup_handler/3</c></seealso>, <c>Arg</c> is the <c>Args</c> argument of this function call.</p> <p><c>Arg={stop,Reason}</c> if the event handler has a supervised - connection to a process which has terminated with reason + connection to a process that has terminated with reason <c>Reason</c>.</p> <p><c>Arg=stop</c> if the event handler is deleted because the event manager is terminating.</p> - <p>The event manager will terminate if it is part of a supervision - tree and it is ordered by its supervisor to terminate. - Even if it is <em>not</em> part of a supervision tree, it will - terminate if it receives an <c>'EXIT'</c> message from - its parent.</p> + <p>The event manager terminates if it is part of a supervision + tree and it is ordered by its supervisor to terminate. + Even if it is <em>not</em> part of a supervision tree, it + terminates if it receives an <c>'EXIT'</c> message from + its parent.</p> <p><c>Arg=remove_handler</c> if the event handler is deleted because another callback function has returned <c>remove_handler</c> or <c>{remove_handler,Reply}</c>.</p> @@ -660,104 +833,20 @@ gen_event:stop -----> Module:terminate/2 or <c>Arg={error,{'EXIT',Reason}}</c> if a callback function failed.</p> <p><c>State</c> is the internal state of the event handler.</p> - <p>The function may return any term. If the event handler is - deleted due to a call to <c>gen_event:delete_handler</c>, - the return value of that function will be the return value of this + <p>The function can return any term. If the event handler is + deleted because of a call to <c>gen_event:delete_handler/3</c>, + the return value of that function becomes the return value of this function. If the event handler is to be replaced with another event - handler due to a swap, the return value will be passed to + handler because of a swap, the return value is passed to the <c>init</c> function of the new event handler. Otherwise the return value is ignored.</p> </desc> </func> - <func> - <name>Module:code_change(OldVsn, State, Extra) -> {ok, NewState}</name> - <fsummary>Update the internal state during upgrade/downgrade.</fsummary> - <type> - <v>OldVsn = Vsn | {down, Vsn}</v> - <v> Vsn = term()</v> - <v>State = NewState = term()</v> - <v>Extra = term()</v> - </type> - <desc> - <p>This function is called for an installed event handler which - should update its internal state during a release - upgrade/downgrade, i.e. when the instruction - <c>{update,Module,Change,...}</c> where - <c>Change={advanced,Extra}</c> is given in the <c>.appup</c> - file. See <em>OTP Design Principles</em> for more - information.</p> - <p>In the case of an upgrade, <c>OldVsn</c> is <c>Vsn</c>, and - in the case of a downgrade, <c>OldVsn</c> is - <c>{down,Vsn}</c>. <c>Vsn</c> is defined by the <c>vsn</c> - attribute(s) of the old version of the callback module - <c>Module</c>. If no such attribute is defined, the version - is the checksum of the BEAM file.</p> - <p><c>State</c> is the internal state of the event handler.</p> - <p><c>Extra</c> is passed as-is from the <c>{advanced,Extra}</c> - part of the update instruction.</p> - <p>The function should return the updated internal state.</p> - </desc> - </func> - <func> - <name>Module:format_status(Opt, [PDict, State]) -> Status</name> - <fsummary>Optional function for providing a term describing the - current event handler state.</fsummary> - <type> - <v>Opt = normal | terminate</v> - <v>PDict = [{Key, Value}]</v> - <v>State = term()</v> - <v>Status = term()</v> - </type> - <desc> - <note> - <p>This callback is optional, so event handler modules need - not export it. If a handler does not export this function, - the gen_event module uses the handler state directly for - the purposes described below.</p> - </note> - <p>This function is called by a gen_event process when:</p> - <list type="bulleted"> - <item>One - of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso> - is invoked to get the gen_event status. <c>Opt</c> is set - to the atom <c>normal</c> for this case.</item> - <item>The event handler terminates abnormally and gen_event - logs an error. <c>Opt</c> is set to the - atom <c>terminate</c> for this case.</item> - </list> - <p>This function is useful for customising the form and - appearance of the event handler state for these cases. An - event handler callback module wishing to customise - the <c>sys:get_status/1,2</c> return value as well as how - its state appears in termination error logs exports an - instance of <c>format_status/2</c> that returns a term - describing the current state of the event handler.</p> - <p><c>PDict</c> is the current value of the gen_event's - process dictionary.</p> - <p><c>State</c> is the internal state of the event - handler.</p> - <p>The function should return <c>Status</c>, a term that - customises the details of the current state of the event - handler. Any term is allowed for <c>Status</c>. The - gen_event module uses <c>Status</c> as follows:</p> - <list type="bulleted"> - <item>When <c>sys:get_status/1,2</c> is called, gen_event - ensures that its return value contains <c>Status</c> in - place of the event handler's actual state term.</item> - <item>When an event handler terminates abnormally, gen_event - logs <c>Status</c> in place of the event handler's actual - state term.</item> - </list> - <p>One use for this function is to return compact alternative - state representations to avoid having large state terms - printed in logfiles.</p> - </desc> - </func> </funcs> <section> - <title>SEE ALSO</title> - <p><seealso marker="supervisor">supervisor(3)</seealso>, - <seealso marker="sys">sys(3)</seealso></p> + <title>See Also</title> + <p><seealso marker="supervisor"><c>supervisor(3)</c></seealso>, + <seealso marker="sys"><c>sys(3)</c></seealso></p> </section> </erlref> |